2010-03-02 270 views
6

我的开发环境是VS2008,DX9,Windows XP。 我尝试将保护处理添加到内存不足的情况。 当malloc返回NULL时,我会将一些资源分页到磁盘,并释放内存中的资源。为什么malloc总是返回NULL

但有时候,总是的malloc返回NULL,即使我释放大部分的资源和进程的内存使用和虚拟机的大小只有在任务管理器800MB。

我想用malloc分配88个字节应该是罚款,在进程的内存使用只有800MB。但malloc总是返回NULL。

难道这是内存碎片?它看起来不是这样,因为进程内存使用量不是太多。

alt text http://i.imagehost.org/0267/Snap2.jpg

+1

你能告诉我们一些代码吗? – 2010-03-02 06:15:41

+0

Exe由VS调试器启动并附加。 – Buzz 2010-03-02 06:15:44

+0

void * AllocCRT(size_t size) { return malloc(size); } 内存使用:644,088K VM大小:671,064K – Buzz 2010-03-02 06:17:26

回答

2

你提到内存碎片,那肯定将是我的第一个猜测。尝试下载this应用程序。它叫地址空间监视器,应该能够告诉你它是否存在碎片问题。

+1

本监视器将分析他处理OS所看到的地址空间,而MSVC中的'malloc'则通过Windows Heap API工作。它不直接从系统分配内存,也不直接将其返回给系统。这意味着这个Monior将无法向你展示任何东西。对于像这样的显示器来说,整个程序堆看起来像是一个永远分配内存的坚实的不可逾越的黑盒子。 – AnT 2010-03-02 06:29:38

+0

@AndreyT:我认为'不会给你任何东西'有点强。进程堆使用用户地址空间,以便您可以看到何时已用尽;这并不一定意味着malloc将无法分配堆已经保留的内存。它应该如此是当有空闲的地址空间时,如果需要分配比已经保留的内存更多的内存,堆应该能够声明。 – 2010-03-02 06:45:03

2

这可能是虚拟地址空间碎片。一种检查方法是致电HeapCompact(GetProcessHeap(), 0)。如果这释放了足够的记忆,那么这就是可能的原因。

另一个类似的原因会从调试器被启动;导致Windows使用调试堆,这在很长一段时间内存在非常糟糕的行为。要禁用该行为,请在环境中设置_NO_DEBUG_HEAP=1并运行。

0

另一种可能是您的程序中可能存在一个错误。你认为你要求88字节,但也许你传递了一个未初始化的变量并要求数百兆字节。或者,也许你之前做过的一些事情是过度运行一个缓冲区并损坏了堆,导致malloc()永远失败。

相关问题