3

これがWindowsの簡単な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);


}

プログラムを実行すると、メモリは約2MBの低さを維持し、100MBの配列をポインタに割り当てると、メモリ使用量は約100MBに跳ね上がります。これは問題ありません。ただし、空きメモリが残った後(私はタスクマネージャを見ています)、プログラムの最後まで100MBです。

私はそれがウィンドウズのページファイルキャッシュか何かにあるかもしれないと思ったので、私は単純な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 ..

それで、私は何を間違っているのですか、それともこれはバグですか?

4

5 に答える 5

3

それは、無料がどのように実装されるかによって異なります。興味深い読み物として、Doug Lea の allocatorを見てください。これは、さまざまなサイズにまたがるメモリ要求を効率的に管理しようとしています。彼の主な関心事は、mallocfreeの呼び出しが高速で正確であることです。

しかし、彼メモリを OS に戻す問題について言及し、それを妨げるもの (メモリの断片化) とそれを助けるもの ( mmapの使用、または柔軟性の低い方法であるsbrk ) について説明します。この記事を読めば、メモリが OS に頻繁に返されないというトレードオフについて、より明確に理解できるでしょう。

于 2009-08-14T18:30:45.540 に答える
2

これは、Digital Mars の malloc と free の実装が、そのような巨大なチャンクを割り当てた場合でも、OS にメモリを返さないことを意味します。代わりに malloc と free from msvcrt.dll を使用してみると、メモリが解放される可能性があります。

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

于 2009-08-14T20:01:54.017 に答える
2

「free」でメモリを解放すると、実際にはメモリが解放されない可能性があります。

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

于 2009-08-14T17:47:29.200 に答える
1

変ですね。Tango のソースを見ると、tango.stdc.stdlib の malloc/free は単なる C 標準ライブラリ関数であるため、違いはないはずです。実際、Linux で Phobos と std.c.stdlib を使用して試してみると、 、メモリは正常に元に戻ります。

あなたはそれを正しく測定していますか?

PS: armageddon[0 .. total_n] = 5; を実行できます。

PS2: あなたの Tango コードを Linux で試してみましたが、期待どおりに戻りました。Windowsの問題のようです。

于 2009-08-14T18:53:19.177 に答える
0

_heapmin() を見ることから始めることができます。free() は未使用のヒープを OS に返さず、空きとしてマークし、最も近い空きの隣接ヒープと結合するだけです。

于 2009-08-14T18:05:18.680 に答える