强制Windows释放已分配的内存

时间:2012-12-28 22:35:43

标签: c++ windows memory memory-management free

我在这里处理一些奇怪的场景,但这正是我计划创建的。它只是一种特殊的测试软件......

我的环境:MSVS 2012,Windows 7/8 32b / 64b。

所以,首先我要创建一些内部结构/缓冲区/等在我的应用程序中使用,然后我正在做这样的事情(这里简化一下,请把它当作伪代码处理):

{
   std::deque<boost::scoped_array<unsigned char>> deque;
   try {
     while (1) {
       deque.push_back(boost::scoped_array<unsigned char>(new unsigned char[system_page_size])); // happens to be 4096 on my system
     }
   }
   catch (std::bad_alloc& ex) { ... }
   // do something here
}

我需要尽可能多地使用内存。我一次分配整个页面(也许这很糟糕,应该为deque / smart ptr的数据留出一些空间?)。当CRT决定不再可能进行分配时,我会做更多的事情(根本不依赖于任何内存可用性),然后退出范围。它将触发析构函数链,所有这些数据都应该被释放。

这很有效。但我偶然进入这个奇怪的范围而不是一次,而是循环10次。它有时可以工作2到3次。有时只有一次。下次我将只获得内存错误,就是这样。

从我的角度来看,我需要重新启动整个过程才能真正强制释放内存。有没有一种方法可以在单一过程中实现这一目标?

我可以考虑尝试不同的分配器 - 也许是CRT问题?我也玩堆操作(即低碎片堆),但也没有帮助。

2 个答案:

答案 0 :(得分:0)

为什么不使用MEM_RESERVE通过一些大型VirtualAlloc调用来保留进程的整个内存空间。然后,您将在稍后的每个内存范围内调用VirtualFree以释放。这仍然需要一些堆分配,就像你在这里用来耗尽当前堆的剩余部分一样。它会更快,并删除您必须经历的页面文件流失。

至于你的具体问题,我不知道你为什么会遇到它。保留所有内存以使堆无法扩展应该有助于减少非确定性。

答案 1 :(得分:0)

如果你使用大量的内存,使用某种slab-allocation(VirtualAlloc将为你提供内存)然后,原则上[假设你在该块中创建的对象不需要析构函数来做一些事情,你可以一次性扔掉整个街区,而不是多次使用删除 - 还有节省时间和保证你的记忆已被完全释放的额外好处。

我怀疑你可能遇到问题的一个原因是,在被回收之前必须清除已释放的块。这是在内核中的后台线程中完成的。当然,使用VirtualALloc实际上对此帐户没有帮助。

当然也可能会出现内存碎片,在这种情况下使用专为避免这种情况而设计的磁头会起作用。