Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C++;服务器程序?_C++_Visual C++_Memory_Heap Fragmentation - Fatal编程技术网

C++ 如何在C++;服务器程序?

C++ 如何在C++;服务器程序?,c++,visual-c++,memory,heap-fragmentation,C++,Visual C++,Memory,Heap Fragmentation,堆碎片可能会导致预期连续运行数月的服务器应用程序突然出现故障,认为内存不足 让我们假设我已经尽了最大努力在我的VC++服务器应用程序中最小化运行时堆碎片,但它仍然会累积并导致问题。例如,我可以每月或每处理50万个请求自动重新启动应用程序—安全地停止它,并使用新堆安全地重新启动。我还可以做些什么来解决堆碎片问题?答案与此处相同: 编写适合内存分配模式的内存管理器。或者买一个(例如智能堆) 由于碎片取决于内存分配模式/释放模式,因此很难给出更好的答案。但您可以查看固定大小的分配器,或者查看它们如何处

堆碎片可能会导致预期连续运行数月的服务器应用程序突然出现故障,认为内存不足

让我们假设我已经尽了最大努力在我的VC++服务器应用程序中最小化运行时堆碎片,但它仍然会累积并导致问题。例如,我可以每月或每处理50万个请求自动重新启动应用程序—安全地停止它,并使用新堆安全地重新启动。我还可以做些什么来解决堆碎片问题?

答案与此处相同:

编写适合内存分配模式的内存管理器。或者买一个(例如智能堆)

由于碎片取决于内存分配模式/释放模式,因此很难给出更好的答案。但您可以查看固定大小的分配器,或者查看它们如何处理分配。关于这个话题也有很多论文。举个例子

或者你可以看看-这是开源的,但在Pascal/Delphi中


还有一些编程技术。最值得注意的是:。在这种情况下,不会出现碎片,因为对象会被重复使用而不会被释放。但我认为固定大小的分配器比对象池性能更好。以这种方式使用的对象池只是一个“穷人”固定大小的分配器。

而不是根据时间或请求数安排重新启动,您可以检查堆,查看碎片何时达到最大连续内存块低于某个级别的级别—毕竟—当不是所有内存都用完时,而是当您尝试分配大于内存中最大可用连续空间大小的对象时,您将开始看到内存不足错误堆


您可以使用来遍历堆并找到最大的可用连续区域。有关如何执行此操作的示例,请参阅。

一个好的起点是启用低碎片堆,并检查它是否仍然存在碎片

  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));
  }
处理堆[1025];
DWORD nheaps=GetProcessHeaps((sizeof(heaps)/sizeof(HANDLE))-1,heaps;
对于(DWORD i=0;i
新引入的内存管理器在Vista/Server 2008上默认打开。。。 所以,如果您确定在较新的服务器操作系统上的世界更好,这可能就是原因

低碎片堆是在Windows 2000 service pack中引入的,但它必须在Windows Vista之前一直处于启用状态


有一种工具可以简单地概述内存,并在出现碎片时提供良好的概述。

显而易见的解决方法是挖掘过去发明的旧解决方案。例如,移动对象的不透明句柄,而不是原始指针。这允许您对堆进行碎片整理。

这些是最小化碎片的好方法,但不是解决碎片问题的好方法。我想sharptooth会问如果他的程序检测到堆碎片,该怎么办。是的,没错。一种策略是定期重启。我还能做什么?防止堆碎片。其他:释放尽可能多的内存,然后重新分配。尝试释放靠近的内存区域。VMMap是一个很好的发现。谢谢。注意,上面的代码在两个方面是不正确的!1.nheaps可以大于1023。那么访问冲突是可能的。读取GetProcessHeaps上的MSDN。首先像这样调用它:GetProcessHeaps(0,NULL)以获取堆计数,然后分配适当的缓冲区。2.MSDN明确指出,您应该仅出于调试目的使用GetProcessHeaps结果。因此,一旦获得堆,它们可能已经更改(即关闭)。这些句柄的使用是未定义的行为……这就是苹果的Mac如何在128k内存中运行整个窗口操作系统和应用程序。这在今天看来是不可能的。