强制Windows释放已分配的内存

Forcing Windows to free allocated memory

本文关键字:内存 分配 Windows 释放 强制      更新时间:2023-10-16

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

我的环境: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的问题?我也玩了一点堆操作(即低碎片堆),但也没有帮助。

为什么不使用MEM_RESERVE使用几个大型VirtualAlloc调用来保留进程的整个内存空间呢?然后在稍后的每个内存范围中调用VirtualFree来释放。这仍然需要一定数量的堆分配,就像您在这里所做的那样,以耗尽当前堆的剩余空间。它将更快,并消除您必须经历的页面文件混乱。

关于你的具体问题,我不知道你为什么会遇到这种情况。保留所有内存,这样堆就不能扩展,这应该有助于减少不确定性。

如果您正在使用大量内存,使用某种slab-allocation会给你(VirtualAlloc保留内存的内存),原则上(假设你的对象中创建块不需要析构函数做),你可以扔掉整个块,而不是使用删除无数倍的好处,节省时间,以及保证你的记忆已经完全释放。

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

当然也有可能出现内存碎片,在这种情况下,使用设计来避免这种情况的磁头是可行的。