2009-08-14 85 views
3

這裏是在窗口的簡單d /探戈代碼:malloc和免費的D /探戈不釋放內存?

module d_test.d; 

import tango.util.log.Trace; 
import tango.core.Thread; 
import tango.stdc.stdlib : malloc, free; 

void main() { 

    Trace.formatln("Checking in..."); 
    Thread.sleep(10); 

    int total_n = (100 * 1000 * 1000)/int.sizeof; // fill mem with 100MB of ints 
    int* armageddon = cast(int*)malloc(total_n * int.sizeof); 

    for(int i = 0; i < total_n; ++i) { 
     armageddon[i] = 5; 
    } 

    Trace.formatln("Checking in..."); 
    Thread.sleep(10); 

    free(armageddon); 
    armageddon = null; 

    Trace.formatln("Checking in..."); 
    Thread.sleep(10); 


} 

當我運行該程序時,存儲器保持爲低〜2MB,當我分配100MB的陣列的指針存儲器使用跳轉到〜100MB,這很好。但是,在空閒內存仍然是(我在看任務管理器)100MB到程序結束。

我想這可能是到Windows頁面文件緩存或東西,所以我已經嘗試了簡單的C++程序:

#include <iostream> 
#include <windows.h> 

using namespace std; 

int main() { 

    Cout << "Checking in..." <<< endl; 
    Sleep(10000); 


    int total_n = (100 * 1000 * 1000)/sizeof(int); 
    int* armageddon = (int*)malloc(total_n * sizeof(int)); 

    for(int i = 0; i < total_n; ++i) { 
    armageddon[i] = 5; 
    } 

    Cout << "Checking in..." <<< endl; 
    Sleep(10000); 

    free(armageddon); 
    armageddon = NULL; 

    Cout << "Checking in..." <<< endl; 
    Sleep(10000); 


return 0; 
} 

我和G ++編譯它,一切似乎工作像它應該。當程序啓動 - 內存使用〜900kb,分配後〜100MB,免費後〜1,2MB ...

那麼,我做錯了什麼或這是一個錯誤?

+1

malloc和free是C調用的說唱歌手。我不知道爲什麼結果會有所不同。 – 2009-08-14 19:08:59

+6

喲喲! //我的名字是malloc,我是一個壞蛋說唱歌手。 //給我所有喲'mem'ry,然後我會把它扔進垃圾箱 – Baxissimo 2009-08-14 21:36:08

回答

3

這取決於如何實現免費。對於一些有趣的閱讀,看看Doug Lea's allocator,它試圖有效地管理可以跨越多種大小的內存請求。他主要關注的是,呼叫速度快,而且正確。

但他提回內存,操作系統的問題,並討論什麼阻礙了它(記憶碎片),什麼有助於它(使用MMAP,或在一個不太靈活的方式,SBRK) 。一旦你閱讀了這篇文章,你就會更清楚地瞭解導致內存不經常回到操作系統的權衡。

2

當你用「free」釋放內存時,很可能它並沒有釋放內存。

這可能是因爲它只是簡單地將它標記爲空閒,但如果稍後請求更多內存,則可以保留它。如果由於某種原因系統開始在內存上運行不足,運行時可能實際上在此時釋放它。

+0

好吧,如果那是真的 - 你知道一個方法來強制釋放它嗎? – Keyframe 2009-08-14 17:53:02

+0

你爲什麼需要它返回到操作系統?只要你有交換空間,擁有未使用的數據空間幾乎沒有成本。 – BCS 2009-08-14 20:27:06

+0

@BCS我正在監視我的程序進程內存使用情況,以便進行性能分析,因爲如果需要,我想限制使用的內存總量。而且我也很好奇爲什麼它的工作原理就像它的工作原理一樣,我怎麼能按照我想要的方式來做。 – Keyframe 2009-08-14 21:39:46

0

您可以先查看_heapmin()。 free()不會將未使用的堆返回給操作系統,它只會將其標記爲空閒並與最近的空閒鄰居合併。

1

這很奇怪。從查看Tango源文件,tango.stdc.stdlib中的malloc/free只是C標準庫函數,所以應該沒有什麼區別 - 事實上,當我在Linux下使用Phobos和std.c.stdlib進行嘗試時,內存會馬上恢復正常。

你確定你正在測量它嗎? PS:你可以做armageddon [0 .. total_n] = 5;

PS2:我在Linux下試過了你的Tango代碼,並且如預期的那樣回落。看起來像一個Windows問題。

2

這只是意味着即使分配了這樣一個巨大的塊,Digital Mars的malloc和free的實現也不會將內存返回到操作系統。您可以嘗試使用malloc並從msvcrt.dll中免費,也許他們會釋放內存。

或者,您可以直接使用Windows API,如果此問題僅對Windows上的DMD存在。最簡單的方法是使用HeapAlloc和HeapFree函數,但我不知道他們是否會做你想做的。一個可靠的方法是更低層次的VirtualAlloc和VirtualFree,它們直接從操作系統分配,而不是先創建堆。這些也是HeapAlloc,malloc,C++等新功能在他們向操作系統請求內存時最終使用的功能。

+1

檢查你是否可以使用DMC(數字火星C++編譯器)的C++程序作爲IIRC,它使用與D相同的malloc。 – BCS 2009-08-14 20:25:12