堆碎片可能会导致预计将持续数月运行突然启动错误的思想,它的出内存的服务器应用程序。
让我们假设我已经做了我所能,以尽量减少在我的VC ++服务器应用程序运行时堆碎片,但仍它建立起来,会引起问题。 我可以例如每月或每处理每半万个请求自动重新启动应用程序 - 安全地停止,并安全地与新堆重新开始。 还有什么我可以做要解决堆碎片?
堆碎片可能会导致预计将持续数月运行突然启动错误的思想,它的出内存的服务器应用程序。
让我们假设我已经做了我所能,以尽量减少在我的VC ++服务器应用程序运行时堆碎片,但仍它建立起来,会引起问题。 我可以例如每月或每处理每半万个请求自动重新启动应用程序 - 安全地停止,并安全地与新堆重新开始。 还有什么我可以做要解决堆碎片?
相同的答案在这里: 如何检测和估算堆碎片在我的C ++程序?
写您自己的内存管理器,适用于你的内存分配模式。 或者买一个(例如智能堆)。
由于碎片取决于你的内存分配模式/释放模式,更好的回答是难以割舍。 但是,你可以看看成固定大小的分配器或者看看在智能堆页面他们如何处理分配。 也有很多关于这个主题的论文。 尝试例如www.memorymanagement.org
或者你可以看看FastMM4 -这是开源的,但在帕斯卡尔/德尔福
有一些编程技巧,以及。 最值得注意的是:在对象池 。 在这种情况下,没有碎裂,作为对象被重新使用,而不是被释放。 但我认为一个固定大小的分配比执行对象池更好。 游泳池使用这种方式的对象仅仅是一个“穷男人的”固定大小分配。
一个很好的出发点是为了使低碎片堆,并检查天气仍然片段。
HANDLE heaps[1025];
DWORD nheaps = GetProcessHeaps((sizeof(heaps) / sizeof(HANDLE)) - 1, heaps);
for (DWORD i = 0; i < nheaps; ++i) {
ULONG enableLFH = 2;
HeapSetInformation(heaps[i], HeapCompatibilityInformation, &enableLFH, sizeof(enableLFH));
}
这种新推出的内存管理器默认情况下,Vista的/ Server 2008上打开......所以,如果你确定世界上较新的服务器操作系统更好,这可能是原因。
低碎片堆是在Windows 2000的服务包推出,但它必须aktively启用,直到Windows Vista中。
有一个工具的VMMap这给存储方便的概述,并提供了一个很好的概述,如果碎片发生。
而不是基于时间或请求的数量安排你的重启,你可以检查堆时看到碎片已经达到的水平时,内存最大连续块低于一定水平 - 毕竟 - 你会开始看到了内存错误而不是当,当所有的内存用完了,但是当你尝试分配比在堆的最大可用连续空间的大小的物体。
您可以使用VirtualQueryEx走你的堆,找到最大的自由连续区域。 有关如何做到这一点的例子,看到这篇文章 。
最明显的解决方法是挖过去被发明的旧的解决方案。 例如,不透明的句柄可移动的物体,而不是原始指针。 这让你整理堆。