2009-08-14 11 views
3

は、Windowsでの単純なD /タン​​ゴコードです:mallocとD/Tangoでメモリを解放しないで無料ですか?ここ

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); 


} 

、私はプログラムを実行すると、メモリが低〜2メガバイトのままで、私は、ポインタのメモリ使用量を100メガバイトの配列を割り当てるとき〜100メガバイトにジャンプそれは問題ありません。しかし、空きメモリがまだ(私はタスクマネージャを見ている)の後に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; 
} 

私は++グラムでそれをコンパイルしたし、すべてがそれが必要のように動作するようです。プログラムが起動するとき - メモリ使用量〜900kb、割り当て後〜100MB、フリー後〜1,2MB ...

どうしたのですか、これはバグですか?

+1

mallocとfreeは、C呼び出しのラッパーです。なぜ結果が違うのか分かりません。 –

+6

よろしく! //私の名前はmallocで、私は悪いラッパーです。 //私に「mem'ry」と言ってください、私はそれを泥棒に投げます。 – Baxissimo

答えて

3

無料がどのように実装されているのかによって異なります。が実装されています。興味深い読書については、Doug Lea's allocatorを見てください。これは、幅広いサイズのメモリ要求を効率的に管理しようとしています。彼の主な関心事は、malloc無料のコールが速く、正しいことです。

しかし、彼ははOSにメモリを返すの問題を言及しない、そしてそれ(メモリの断片化)を阻害するものを説明し、どのようにそれを支援する(mmapの、以下の柔軟な方法での使用、sbrkの) 。この記事を読んだら、OSへのメモリの復帰がまれになるようなトレードオフをより明確に理解することができます。

2

"フリー"でメモリを解放すると、実際にはメモリが解放されていない可能性があります。

単純に空きとしてマークしておきますが、あとでメモリを要求する場合に備えて、それを保持している可能性があります。なんらかの理由でシステムのメモリが不足し始めると、ランタイムは実際にその時点で解放します。

+0

それが本当なら、あなたは力でそれを解放する方法を知っていますか? – Keyframe

+0

なぜOSに戻す必要がありますか?あなたがスワップ領域を持っている限り、未使用のデータ領域にはコストがほとんどありません。 – BCS

+0

@BCS私は必要に応じて使用されるメモリの総量を制限したいので、プロファイリングの目的でプログラムプロセスのメモリ使用量を監視しています。そして、私はそれがうまくいくように、なぜ私が望むようにそれをやり遂げることができるのか、また興味があります。 – Keyframe

0

まずは_heapmin()を見てください。 free()は未使用のヒープをOSに返しません。それは空きとしてマークし、最も近い空きのネイバーと合体します。

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の実装が、そのような巨大なチャンクを割り当てたとしても、OSにメモリを返さないことを意味します。 mallocを使用してみて、代わりにmsvcrt.dllを解放してみてください。おそらくメモリを解放します。

この問題がWindowsのDMDにのみ存在する場合は、Windows APIを直接使用できます。最も簡単なのは、HeapAllocとHeapFree関数を使うことですが、あなたが望むことを彼らがやるかどうかはわかりません。確かに、より低レベルのVirtualAllocとVirtualFreeは、ヒープを最初に作成するのではなく、OSから直接割り当てます。これらは、HeapAlloc、malloc、C++の新機能などが、OSからメモリを要求するときに最終的に使用する関数でもあります。

+1

を使って、DMC(デジタル火星C++コンパイラ)を使用してC++プログラムをIIRCとして試すことができることを確認します。これは、Dと同じmallocを使用します。 – BCS

関連する問題