内存不足_beginthreadex

我目前正在debugging一个multithreading应用程序,它运行没有错误,直到一些函数调用大约2000次。 之后,应用程序停止响应,我可以跟踪_beginthreadex失败,内存不足的错误。

在ProcessExplorer中检查应用程序时,我可以看到越来越多的线程句柄泄漏,虚拟内存越来越大,直到发生错误时,私有字节保持低位。 泄露的线程也调用CoInitialize并从不调用CoUninitialize。

我想知道的是:

  • 虚拟内存代表什么?
  • 与泄漏的线程句柄相关的虚拟内存?
  • COM或MSXML6(由线程调用)复制线程句柄,如何closures它们?

我希望我的问题是清楚的,不要打破任何问题,这是我的第一个问题,英语不是我的第一语言。:-(

我忘了提及,一旦线程终止,我closures由_beginthreadex返回的句柄,这减less了大约一半的打开句柄的数量,但不影响虚拟内存。 另外,在我插入CloseHandle调用之前,ProcessExplorer中显示的每个线程句柄的线程的句柄数为2。

编辑

因为之前我没有包括这个,所以我知道这个线程退出的时候,用Visual Studio进行debugging的时候,线程的数量并没有增加。 我希望不是所有的泄漏内存都是由于调用TerminateThread而导致的,因为它们在一个相当大的库中使用,我不想修改它。

在我的问题的COM部分,用!htrace -diff我发现线程处理由msxml分配,但没有释放后functioncalls结束,他们可能与泄漏有关,或将在稍后closures?

感谢所有这些意见,而问题仍然存在,他们帮助我更好地理解。

一个进程可用的虚拟内存是2Gb的4Gb地址空间。 每个线程默认为其堆栈空间保留约1Mb的虚拟内存空间。 因此,在虚拟内存耗尽之前,win32应用程序具有大约2000个活动线程的限制。

虚拟内存是应用程序在像Windows那样的现代虚拟内存操作系统中获得的内存。 在Win32上会发生什么,您的应用程序会获得2Gb的虚拟地址空间。 当你的程序调用new或者malloc时,经过几层的隧道之后,空间被分配给你的应用程序ON DISK–在页面文件中。 当CPU指令尝试访问该内存时,会抛出硬件异常,内核会为该区域分配物理RAM,并从页面文件中读取内容。 所以,不管PC中的物理RAM如何,每个应用程序都认为它可以访问整个2Gb。 虚拟内存是你的2Gb空间用完了多少。

每个线程(见上文)为其堆栈预留1 Mb的虚拟地址空间。 大多数1Mb只是保留空间(希望)没有RAM或页面文件的支持。

关闭线程句柄时,不要关闭线程。 线程被另一个调用TerminateThread的线程终结(它泄漏线程栈和其他一些资源,所以永远不要使用它),自己调用ExitThread(),或者退出ThreadProc。

因此,在2000年的调用限制,无与伦比的CoInitialize和CoUninitialize调用,我会说你的线程不是干净的或完全退出。 2000个工作线程中的每一个线程在完成工作后都停留在做某件事而不是退出。

_beginthreadex / _endthreadex函数不会自动关闭线程句柄,因此您必须调用win32 CloseHandle函数关闭它。 句柄是由_beginthreadex返回的值。 如果使用_beginthread / _endthread ,则句柄将自动关闭。

关于虚拟内存:它表示保留的内存,但不一定使用。 泄漏的内存(或至少部分内存)与手柄泄漏有关。 当线程的最后一个句柄关闭时,Windows将释放为其保留的虚拟内存。