malloc和免费在D / Tango没有释放记忆?

时间:2009-08-14 17:38:10

标签: memory d tango

这是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。

我认为它可能是windows pagefile缓存或其他东西,所以我尝试了一个简单的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 ......

那么,我做错了什么或这是一个错误?

5 个答案:

答案 0 :(得分:3)

这将取决于免费的实施方式。对于一些有趣的阅读,请查看Doug Lea's allocator,它试图有效地管理可以跨越各种大小的内存请求。他主要担心的是 malloc 免费调用是否快速且正确。

但他确实提到了将内存返回给操作系统的问题,并讨论了阻碍它的内容(内存碎片)及其帮助(使用 mmap ,或者一种不太灵活的方式, sbrk )。一旦你阅读了这篇文章,你就会更清楚地了解导致不经常将内存返回给操作系统的权衡。

答案 1 :(得分:2)

当你用“免费”释放内存时,它可能实际上没有释放内存。

可能是它只是将其标记为免费,但如果您稍后请求更多内存,则可以保留它。如果由于某种原因系统内存开始运行不足,那么运行时可能会在那时释放它。

答案 2 :(得分:2)

这只是意味着Digital Mars对malloc和free的实现不会将内存返回给操作系统,即使你分配了大量的内存。您可以尝试使用malloc并免费使用msvcrt.dll,也许他们会释放内存。

或者,如果此问题仅存在于Windows上的DMD,则可以直接使用Windows API。最简单的方法是使用HeapAlloc和HeapFree函数,但我不知道它们是否也能做你想做的事情。一种可靠的方法是更低级别的VirtualAlloc和VirtualFree,它们直接从操作系统分配,而不是先创建堆。这些也是HeapAlloc,malloc,C ++等新功能,当它们从操作系统请求内存时最终使用的功能。

答案 3 :(得分:1)

这很奇怪。从Tango源看,tango.stdc.stdlib中的malloc / free只是C标准库函数,所以应该没有区别 - 实际上,当我在Linux下使用Phobos和std.c.stdlib进行尝试时,记忆会正确地回落。

你确定你正在测量它吗?

PS:你可以做一次世界末日[0 .. total_n] = 5;

PS2:我在Linux下尝试了你的Tango代码,它按预期的那样回落了。看起来像Windows问题。

答案 4 :(得分:0)

您可以先查看_heapmin()。 free()不会将未使用的堆返回给操作系统,它只会将其标记为空闲并与最近的自由邻居合并。