jos*_*efx 5 c++ windows com multithreading handle
我目前正在调试一个多线程应用程序,它运行时没有错误,直到一些函数被调用大约2000次.之后,应用程序停止响应,我可以追溯到_beginthreadex失败并出现内存不足错误.
在ProcessExplorer中检查应用程序时,我可以看到越来越多的线程句柄泄露,并且在发生错误之前虚拟内存不断增长,私有字节保持低位.泄露的线程也调用CoInitialize,从不调用CoUninitialize.
我想知道的是:
我希望我的问题很明确,不会破坏任何问题,这是我的第一个问题,英语不是我的第一语言.:-(
我忘了提一下,一旦线程终止,我关闭_beginthreadex返回的句柄,这会将打开句柄的数量减少一半,但不会影响虚拟内存.另外,在我插入CloseHandle调用之前,ProcessExplorer中显示的每个线程句柄的线程句柄数为2.
编辑
之前没有包括这个,我感到愚蠢,我知道线程退出时活动线程的数量与Visual Studio调试时不会增长.我希望并不是所有泄露的内存都是调用TerminateThread的结果,因为它们被用在一个相当大的库中,我宁愿不修改它.
对于我的问题的com部分,使用!htrace -diff,我发现msxml分配的线程句柄但在函数调用结束后没有释放,它们是否与泄漏有关,或者它们将在以后关闭?
感谢所有这些评论,虽然问题仍然存在,但他们帮助我更好地理解它.
进程可用的虚拟内存是 4Gb 地址空间中的 2Gb。每个线程默认为其堆栈空间保留大约 1Mb 的虚拟内存空间。因此,在虚拟内存耗尽之前,win32 应用程序的活动线程数量限制为大约 2000 个。
虚拟内存是应用程序在现代虚拟内存操作系统(如 Windows)中获得的内存。在 Win32 上发生的情况是,您的应用程序获得 2Gb 的虚拟地址空间。当您的程序调用 new 或 malloc 时,经过几层隧道后,会在磁盘上(在页面文件中)为您的应用程序分配空间。当 CPU 指令尝试访问该内存时,会抛出硬件异常,内核会将物理 RAM 分配给该区域,并从页面文件中读取内容。因此,无论 PC 中的物理 RAM 有多少,每个应用程序都认为它可以访问整个 2Gb。虚拟内存是对 2Gb 空间已使用量的计数。
每个线程(见上文)保留 1 Mb 虚拟地址空间以供其堆栈增长。这 1Mb 中的大部分只是保留空间(希望如此),没有 RAM 或页面文件的支持。
当您关闭线程句柄时,您并没有关闭该线程。线程由另一个线程调用 TerminateThread(这会泄漏线程堆栈和其他一些资源,因此永远不要使用它)、调用 ExitThread() 本身或从其 ThreadProc 退出来终止。
因此,由于 2000 个调用限制、不匹配的 CoInitialize 和 CoUninitialize 调用,我想说您的线程没有完全退出或根本没有退出。2000 个工作线程中的每一个都陷入困境,而不是在完成工作后退出。