关键部分泄漏Vista/Win2008上的内存? [英] Critical Sections leaking memory on Vista/Win2008?

查看:86
本文介绍了关键部分泄漏Vista/Win2008上的内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎在Vista/Windows Server 2008中大量使用关键部分会导致操作系统无法完全重新获得内存. 我们在Delphi应用程序中发现了这个问题,这显然是因为使用了CS API. (请参见 SO问题)

It seems that using Critical Sections quite a bit in Vista/Windows Server 2008 leads to the OS not fully regaining the memory. We found this problem with a Delphi application and it is clearly because of using the CS API. (see this SO question)

是否有人用其他语言(C ++,...)开发的应用程序看到了它?

Has anyone else seen it with applications developed with other languages (C++, ...)?

该示例代码只是初始化10000000 CS,然后将其删除.在XP/Win2003中,此方法工作正常,但在应用程序结束之前,不会释放Vista/Win2008中的所有峰值内存.
您使用CS的次数越多,您的应用程序保留的内存就越多.

The sample code was just initialzing 10000000 CS, then deleting them. This works fine in XP/Win2003 but does not release all the peak memory in Vista/Win2008 until the application has ended.
The more you use CS, the more your application retains memory for nothing.

推荐答案

Microsoft确实已经改变了InitializeCriticalSection在Vista,Windows Server 2008以及Windows 7上的工作方式.
他们添加了一个功能",以便在分配一堆CS时保留一些用于调试信息的内存.您分配的越多,保留的内存就越多.它可能是渐近的,并最终变平(对此功能还没有完全购买).
为避免此功能",您必须使用新的API InitalizeCriticalSectionEx 并传递标志CRITICAL_SECTION_NO_DEBUG_INFO.
这样做的好处是,它可能会更快,因为通常仅使用spincount即可,而不必实际等待.
缺点是您的旧应用程序可能不兼容,您需要更改代码,并且它现在依赖于平台(您必须检查版本以确定要使用哪个版本).而且,如果需要,您还会失去调试能力.

Microsoft have indeed changed the way InitializeCriticalSection works on Vista, Windows Server 2008, and probably also Windows 7.
They added a "feature" to retain some memory used for Debug information when you allocate a bunch of CS. The more you allocate, the more memory is retained. It might be asymptotic and eventually flatten out (not fully bought to this one).
To avoid this "feature", you have to use the new API InitalizeCriticalSectionEx and pass the flag CRITICAL_SECTION_NO_DEBUG_INFO.
The advantage of this is that it might be faster as, very often, only the spincount will be used without having to actually wait.
The disadvantages are that your old applications can be incompatible, you need to change your code and it is now platform dependent (you have to check for the version to determine which one to use). And also you lose the ability to debug if you need.

冻结Windows Server 2008的测试工具包:
-将此C ++示例构建为CSTest.exe

Test kit to freeze a Windows Server 2008:
- build this C++ example as 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; 
}

-...运行此批处理文件(需要服务器SDK中的sleep.exe)

-...Run this batch file (needs the sleep.exe from server SDK)

@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

-...,然后看到具有8GB和四CPU内核冻结的Win2008服务器,然后才能启动300个实例.
-...在Windows 2003服务器上重复,然后看到它像魅力一样处理.

-...and see a Win2008 server with 8GB and quad CPU core freezing before reaching the 300 instances launched.
-...repeat on a Windows 2003 server and see it handle it like a charm.

这篇关于关键部分泄漏Vista/Win2008上的内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆