delete記憶體釋放機制

來源:互聯網
上載者:User
同事在項目中使用new/delete的時候發現一個奇怪的現象:
int32_t i;
std::queue<char *> qTest;
for (i = 0; i < 100000; i ++) {
    char *p = new char[100];
    qTest.push(p);
    char *p1 = qTest.front();
    delete[] p1;
    qTest.pop();
}

當在一個迴圈內,如果申請空間,在迴圈內並釋放掉,記憶體不會引起增長,即使重複上面的單元也不會增長記憶體,但是當:

int32_t i;
std::queue<char *> qTest;
for (i = 0; i < 100000; i ++) {
    char *p = new char[100];
    qTest.push(p);
    //char *p1 = qTest.front();
    //delete[] p1;
    //qTest.pop();
}
while( !qTest.empty() ) {
    char *p1 = qTest.front();
    delete[] p1;
    qTest.pop();
}

而發現通過delete[]後,記憶體並沒有減少,即使重複上面的單元,記憶體只會增加,不會減少,用valgrind的memcheck工具查看,也無記憶體流失。
其實,這個與malloc的實現有關,一般來說,系統都會有預設的malloc行為,一般來說(針對FreeBSD和Linux系列),對於大於1M的資料,malloc行為會直接調用系統的介面,直接向作業系統申請一塊比資料區塊更大記憶體,然後劃分成若干過chunk單元(這裡會有一些演算法設計),而這些chunk分配給資料後,肯定還會剩下很多的trunk單元,留給以後的分配用,但這裡耗費系統資源,代價較大;而對於小於等於1M的資料,則malloc行為會利用那些trunk單元,佔用系統資源少,速度快。同理free的時候,資料佔用的記憶體被釋放,如果大於1M,則系統會回收掉記憶體,節省資源,而小於等於1M的資料,則記憶體釋放時,不會還給作業系統,以空trunk形式存在,並由當前進程空間維護著。說到底,這種策略就是一個記憶體池的概念。
記憶體池靈活度更加方便,一般來說(針對FreeBSD和Linux系列),每個trunk最小容納的位元組數是16bytes,而自行設計的記憶體池,可以更加最佳化,節省大量產生的記憶體片段,像上面的代碼就是因為記憶體雖然釋放,但是這些記憶體都沒有還給作業系統,導致記憶體片段越來越多,最好的設計方式就是使用一個記憶體池,針對經常使用的分配大小,可以多分配這樣的trunk,而其他大小的trunk可以少產生,從而達到最佳化目的。
另外,也可以使用mallopt來直接調整malloc的行為:

int mallopt (int PARAM, int VALUE)

     When calling `mallopt', the PARAM argument specifies the parameter
     to be set, and VALUE the new value to be set.  Possible choices
     for PARAM, as defined in `malloc.h', are:

    `M_TRIM_THRESHOLD'
          This is the minimum size (in bytes) of the top-most,
          releasable chunk that will cause `sbrk' to be called with a
          negative argument in order to return memory to the system.

    `M_TOP_PAD'
          This parameter determines the amount of extra memory to
          obtain from the system when a call to `sbrk' is required.  It
          also specifies the number of bytes to retain when shrinking
          the heap by calling `sbrk' with a negative argument.  This
          provides the necessary hysteresis in heap size such that
          excessive amounts of system calls can be avoided.

    `M_MMAP_THRESHOLD'
          All chunks larger than this value are allocated outside the
          normal heap, using the `mmap' system call.  This way it is
          guaranteed that the memory for these chunks can be returned
          to the system on `free'.  Note that requests smaller than
          this threshold might still be allocated via `mmap'.

    `M_MMAP_MAX'
          The maximum number of chunks to allocate with `mmap'.
          Setting this to zero disables all use of `mmap'.
值得注意的是mallopt是malloc底層的函數,需要使用info mallopt來查看相關協助資訊。

[From:http://my.huhoo.net/archives/2010/05/malloptmallocnew.html]

關於mallopt:

http://www.man7.org/linux/man-pages/man3/mallopt.3.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.