2012-02-09 124 views
2

我寫的一個核心基礎應用程序似乎正在消耗更多的內存(根據活動監視器中的「真正的內存」數量)比我實際分配的更多。診斷Mac OS X上的堆碎片?

我已確認我的實際分配是我希望它們通過樂器中的實時字節分配視圖(大約10MB),但活動監視器中的「真實存儲」計數顯示> 60MB,並且顯然正在增長。我也證實沒有泄漏,也使用儀器。

我的應用程序保留了大量不同大小的緩衝區,並且在添加/刪除隊列項時一直釋放緩衝區()和malloc()緩衝區。

在閱讀了關於堆碎片的一些信息之後,這似乎是對正在發生的事情的解釋。所以我的問題如下:

  1. 有沒有什麼辦法來確認這個OS X例如也許得到堆的視覺表示?
  2. 是否有可用於OS X的可選低碎片堆管理器,與Windows一樣?

誰想要複製的問題,下面的示例代碼顯示了相同的症狀相當不錯:

#define MAX_SIZE (10*1024*1024) 

int main (int argc, const char * argv[]) 
{ 

size_t actual_alloc=0; 
size_t max_alloc=0; 

char *bigbuf=NULL; 
size_t bigsize=0; 

for (long x=0; x<10000000; x++) 
{ 
    if (bigbuf!=NULL) 
    { 
     actual_alloc -= bigsize; 
     free(bigbuf); 
    } 

    bigsize = rand() % MAX_SIZE; // alloc random amount up to MAX_SIZE 
    bigbuf = (char*)malloc(bigsize); 
    memset(bigbuf, 'x', bigsize); 
    actual_alloc += bigsize; 

    if (actual_alloc > max_alloc) 
     max_alloc = actual_alloc; 

    if (x%100==0) 
    { 
     printf("alloc = %u \t max = %u\n", 
      (unsigned long)actual_alloc, (unsigned long)max_alloc); 

     // max_alloc tends towards 10MB, 
     // "Real Mem" in activity monitor tends towards 60MB 
    } 
} 


return 0; 
} 

如果從上面的代碼中刪除隨機元素,你避開10MB按預期處理內存使用情況。

回答

2

堆是一個複雜的數據結構,你看到的是正常的。僅僅因爲你釋放()一個緩衝區並不意味着該庫將該內存返回給操作系統。系統調用會產生成本,所以當分配系統要求大量內存時,它往往會要求超過它的需求,以便後續分配可以返回內存而不必轉到內核。堆還可能爲不同分配大小維護多個分配區域,以避免長時間搜索和分段。通過分配隨機大小,你已經設法初始化這些桶中的幾個。

您無法預測內存分配子系統或您鏈接的其他系統庫的行爲,因此活動監視器或頂級或任何其他工具不會爲您提供有意義的信息。如果您想跟蹤內存分配或泄漏,請使用malloc調試器或類似valgrind的工具。

+0

對不起,也許我的問題不清楚,我知道這是正常的行爲。我想知道的是(1)是否有測量堆碎片的工具,所以我可以證明我的應用正在導致它,(2)是否有適用於Windows的低碎片堆管理器OS X。 – snowcrash09 2012-02-09 14:11:55