Fra*_*ois 5 memory-leaks critical-section windows-vista windows-server-2008
似乎在Vista/Windows Server 2008中使用关键部分导致操作系统无法完全恢复内存.我们在Delphi应用程序中发现了这个问题,显然是因为使用了CS API.(见这个问题)
有没有其他人用其他语言开发的应用程序(C++,...)看到它?
示例代码只是初始化10000000 CS,然后删除它们.这在XP/Win2003中运行良好,但在应用程序结束之前不会释放Vista/Win2008中的所有峰值内存.
您使用CS的次数越多,您的应用程序就会越多地保留内存.
微软确实改变了InitializeCriticalSection在Vista,Windows Server 2008以及可能还有Windows 7上的工作方式.
他们在分配一堆CS时添加了一个"功能"来保留用于调试信息的一些内存.分配的越多,保留的内存就越多.它可能是渐近的并最终变平(没有完全买到这个).
要避免此"功能",您必须使用新的API InitalizeCriticalSectionEx并传递标志CRITICAL_SECTION_NO_DEBUG_INFO.
这样做的好处是它可能更快,因为通常只使用spincount而不必实际等待.
缺点是旧的应用程序可能不兼容,您需要更改代码,现在它依赖于平台(您必须检查版本以确定使用哪个版本).如果需要,你也失去了调试的能力.
用于冻结Windows Server 2008的测试工具包:
- 将此C++示例构建为CSTest.exe
#include "stdafx.h"
#include "windows.h"
#include <iostream>
using namespace std;
void TestCriticalSections()
{
const unsigned int CS_MAX = 5000000;
CRITICAL_SECTION* csArray = new CRITICAL_SECTION[CS_MAX];
for (unsigned int i = 0; i < CS_MAX; ++i)
InitializeCriticalSection(&csArray[i]);
for (unsigned int i = 0; i < CS_MAX; ++i)
EnterCriticalSection(&csArray[i]);
for (unsigned int i = 0; i < CS_MAX; ++i)
LeaveCriticalSection(&csArray[i]);
for (unsigned int i = 0; i < CS_MAX; ++i)
DeleteCriticalSection(&csArray[i]);
delete [] csArray;
}
int _tmain(int argc, _TCHAR* argv[])
{
TestCriticalSections();
cout << "just hanging around...";
cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
-...运行此批处理文件(需要来自服务器SDK的sleep.exe)
@rem you may adapt the sleep delay depending on speed and # of CPUs
@rem sleep 2 on a duo-core 4GB. sleep 1 on a 4CPU 8GB.
@for /L %%i in (1,1,300) do @echo %%i & @start /min CSTest.exe & @sleep 1
@echo still alive?
@pause
@taskkill /im cstest.* /f
Run Code Online (Sandbox Code Playgroud)
-...并在启动300个实例之前看到一个8GB和四核CPU核心冻结的Win2008服务器.
-...在Windows 2003服务器上重复并看到它像魅力一样处理它.
| 归档时间: |
|
| 查看次数: |
3728 次 |
| 最近记录: |