如何更好的管理在應用程式中記憶體的使用,同時提高記憶體使用的效率,這是值得每乙個做開發的人深思的問題。記憶體池(memory pool)提供了一種比較可行的解決方案。下面就一般記憶體池的原理與設計進行**。
一般的記憶體池的使用,分為以下幾個過程:
1.建立記憶體池。這個過程的主要任務是預先分配足夠大的記憶體,形成乙個初步的「記憶體池」。這裡在實現的過程中,具體可以這麼做,因為應用程式中不同的地方需要的記憶體的大小不盡相同,所以要在記憶體池中放一些不同大小的記憶體塊,這樣能更好地滿足應用程式對記憶體的需求,同時也能提高記憶體的使用率。舉個例子,可以在記憶體池中放256b, 512b, 1k, 2k, 4k, 8k, 16k, ... , 1m, 2m, 4m大小的記憶體塊。每種塊的個數,可以根據實際情況定,用的頻率比較高的塊可以多分配一些,用得頻率比較低的塊少分配一些。在用c++實現的時候,我的建議是使用map> >結構來管理這記憶體池中的這些記憶體,在該結構中,鍵為記憶體塊的大小,值為所有大小為鍵的記憶體塊的乙個雙向佇列。該佇列中,每個元素有兩部分組成,第一部分是指向該記憶體塊的指標,第二部分是該記憶體塊是否空閒的標誌。
2.分配記憶體。每次使用者要從記憶體中獲取記憶體時,首先要計算出不小於使用者所需要的記憶體大小的在我們的記憶體池中有的最小的記憶體塊的大小。然後去記憶體池中找,這樣大小的記憶體塊是否有空閒的。如果有,就把這塊記憶體返回給使用者。如果沒有的話,可以直接呼叫系統提供的malloc或是new分配一塊記憶體,並且要把這塊記憶體新增到記憶體池中,被把標誌位置為已用狀態。在這裡,要注意的是,盡可能減少直接呼叫malloc或new的次數,否則記憶體池在效率上的優勢就體現不出來了。記憶體池設計的優劣很大程度上也是在這裡決定的。好的設計,可以保證miss率很低,這樣就很好地發揮了記憶體池的優勢。
3.釋放記憶體。記憶體的釋放,不是真正地呼叫free或是delete的過程,而是把內存放回記憶體池的過程。在把記憶體放入記憶體池的同時,要把標誌位置為空閒。
4.銷毀記憶體池。最後在應用程式結束時,要把記憶體池銷毀。這裡主要做的工作就是把記憶體池中的每一塊記憶體釋放。
以上即闡述了一般的記憶體池的原理與設計。每個記憶體池的原理都是一樣的,只是根據不同的應用程式,實現會可能會略有不同。
最後還有幾點要說明一下的:
使用記憶體池的好處:
1.減少了記憶體碎片的產生。這個可以從建立記憶體池的過程中看出。我們在建立記憶體池時,分配的都是一塊塊比較整的記憶體塊,這樣可以減少記憶體碎片的產生。
2.提高了記憶體的使用效率。這個可以從分配記憶體和釋放記憶體的過程中看出。每次的分配與釋放並不是去呼叫系統提供的函式或是操作符去操作實際的記憶體,而是在復用記憶體池中的記憶體。
缺點:1.有可能會造成少量的記憶體浪費。因為分配的記憶體,往往有可能大於使用者實際所需的。但是這個帶來的影響是很小的,實際上是瑕不掩瑜的。
記憶體管理之記憶體定址
記憶體定址 三種記憶體位址 邏輯位址 logical address 包含機器語言指令中用來指定乙個運算元或一條指令的位址 線性位址 linear address 線性位址也稱為虛擬位址 virtual address 實體地址 physical address 用於記憶體晶元級記憶體單元定址,他們...
STL設計思想之記憶體管理
日一二三四五六 31123456 78910111213 14151617181920 21222324252627 2829301234 567891011 allocator看的是sgi的版本,應用了兩級記憶體分配,其中預設情況下以記憶體池 memory pool 策略解決記憶體碎片 fragm...
高效能之記憶體池
記憶體池 memory pool 是一種記憶體分配方式。通常我們習慣直接使用new malloc等api申請分配記憶體,這樣做的缺點在於 由於所申請記憶體塊的大小不定,當頻繁使用時會造成大量的記憶體碎片並進而降低效能。記憶體池則是在真正使用記憶體之前,先申請分配一定數量的 大小相等 一般情況下 的記...