2012-09-22 54 views
2

我正在瀏覽一些實時操作系統規範,我讀到在RTOS中我們通常不喜歡使用malloc。其原因如下:對於性能問題,我們不應該使用malloc,因爲通過malloc分配內存非常耗時,而且開銷會跟蹤分配的內存。內存池與malloc

現在在實時系統中,所有進程都有時間約束,我們通常不使用malloc。我很好奇,開始研究有點像在RTOS運行時如何分配內存,我發現內存池。現在寫道,內存池實際上意味着固定大小的塊分配。內存池的優點是它不會遭受分片。這怎麼可能?假設我們有3個4字節的池,應用程序需要10個字節,所以在這種情況下,內存池將受到內部碎片的影響。

內存池如何工作以及如何分配內存?應用程序在編譯時是否獲得了池,就像一個特定的應用程序將從4字節的池大小中獲得3個池?如果他們需要的內存不適合游泳池,該怎麼辦?這樣的系統中是否存在大量不同大小的內存池?請給我解釋一下。

回答

1

那麼,碎片將取決於內存池的實現。通常,內存池是固定大小的內存塊的池。當某個東西想要一塊大小的內存塊時,它就會進入該池。因此,沒有碎片,因爲所有想要這個大小的塊都會從這個大小的塊中獲得它。

現在,如果特定大小的塊池不存在,則可以使用更大大小的池。如果發生這種情況,則技術上存在碎片,因爲分配的內存塊的某個部分未被使用(碎片化)。

如果所有的內存池都提供了所有需要的大小的塊,那麼就不會有碎片。

0

池不會消除碎片,但它們可以顯着減少碎片,並且還可能減少分配大量非常小的塊的開銷。一個好的方案是允許客戶端代碼爲每個高度縮放的結構創建一個池的庫。在創建池時,可以指定塊大小,最初分配的塊的數量和增長的數量,以及用於調試的文本名稱。

要分配一個塊,請將池標識傳遞給分配器。每當池沒有空閒塊時,它會分配一塊連續的塊並使其可用,並返回其中一塊。每當塊被釋放時,如果該塊的塊中的所有塊都空閒,則釋放該塊。

對於調試,有一個例程可以打印所有的池,給出描述,分配的數量以及可能的其他統計數據,如可用的空閒數量(如果這樣很高,則存在碎片問題)以及最大分配。對尋找內存泄漏非常有幫助。

這種類型的庫最糟糕的情況是分配大量塊的子系統,然後在系統生命早期釋放它們中的大部分。許多塊將保持分配,但使用的塊很少。最好的情況(與malloc相比)是需要持續循環的,需要具有廣泛不同壽命的新塊,對於需要長時間保持的系統,如某些嵌入式系統。

這是最簡單的,適用於單線程應用程序。對於多線程應用程序,必須注意使其線程安全,並且您可能需要模擬malloc()經常在封面下進行的優化,以最大限度地減少鎖定開銷(例如,每線程「arenas」)。