2016-05-12 151 views
10

當我使用malloc() s和free() s隨機,嵌套和不同的大小,在某些時候內存將被分割,因爲這些操作留下了一大堆小的內存區域後面是非連續的,因此可以' t被分配爲一個更大的塊。內存碎片

在這幾個問題:

  • 當這往往使內存被強制零散完成,然後所有這些內存區域free() d,我可以假設這些空白區連接回原來的連續大小?

  • 當我總是做一個malloc()隨後free()爲相同的內存,從不窩這些呼叫,在這種情況下支離破碎的記憶太分配時/釋放的大小總是不同?

+6

所有這些都取決於實施。但是,是的,一個好的內存管理器會連接連續的空閒內存部分。而且,是的,如果您執行'malloc'然後是'free',並且您不調用任何調用'malloc'的庫函數,則不會發生碎片。 –

+2

您可以使用程序http://www.valgrind.org運行Valgrind,並檢查數據對齊錯誤和內存泄漏。 –

+0

這是很難分割64位地址空間。當然,你可以很容易地將它分割成不能再分配10TB的對象,但是你可能沒有10TB的RAM。 – MSalters

回答

2

作爲每ISO/IEC 9899:201X - > 7.22.3

的順序和通過向 連續調用的aligned_alloc,釋放calloc,malloc和realloc函數分配的存儲的鄰接是 未指定。

一個好的內存管理器將能夠在一定程度上解決這個問題。但是,還有其他方面,如導致內部碎片的數據對齊[1]

如果您依賴內置內存管理,您可以做些什麼?

  1. 使用分析器 - 說的valgrind - 內存檢查選項發現在使用後沒有釋放的內存。 例子:

    valgrind --leak-check=yes myprog arg1 arg2 
    
  2. 遵循良好做法。例子 - 在C++中,如果你打算別人從你的多態類繼承,你可以聲明它的析構函數是虛擬的。

  3. 使用智能指針。

注:

  1. Internal fragmentation

  2. 如果您要使用自己的內存管理系統,可以考慮Boehm-Demers-Weiser垃圾回收器。

  3. Valgrind儀表框架。

  4. 使用後未釋放內存將導致碎片。
5

不,沒有保證。據N1570,7.22.3 Memory management functions

的秩序,並以 連續調用的aligned_alloc,釋放calloc,malloc和realloc函數分配的存儲空間的連續性是 不確定的。

無論如何,你有兩個選擇可供選擇:

  1. 完全信任庫內存管理功能。
  2. 寫你自己的內存管理器,如果你真的有信心。

如果我是你,我肯定會信任現有的功能,因爲現代實現是超級智能的。

+0

其實,因爲問題是(也)標記爲C++,這兩種可能性並不相互排斥,您可以按類重寫'operator new'。 – MSalters