gpt4 book ai didi

c++ - _beginthreadex 内存不足

转载 作者:可可西里 更新时间:2023-11-01 13:30:01 27 4
gpt4 key购买 nike

我目前正在调试一个多线程应用程序,它运行时没有错误,直到某些函数被调用了大约 2000 次。之后应用程序停止响应,我可以追踪到 _beginthreadex 因内存不足错误而失败。

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

我想知道的是:

  • 虚拟内存代表什么?
  • 虚拟内存是否与泄漏的线程句柄有关?
  • COM 或 MSXML6(由线程调用)是否复制线程句柄以及如何关闭它们?

我希望我的问题很清楚并且不会违反任何规则,这是我的第一个问题,英语不是我的第一语言。:-(

我忘了说,一旦线程终止,我就会关闭 _beginthreadex 返回的句柄,这会将打开的句柄数量减少大约一半,但不会影响虚拟内存。此外,在我插入 CloseHandle 调用之前,ProcessExplorer 中显示的每个线程句柄的线程句柄数为 2。

编辑

我之前因为没有包括这个而变得愚蠢,我知道线程退出时事件线程的数量在使用 visual studio 进行调试时不会增长。我确实希望并非所有泄漏的内存都是调用的结果到 TerminateThread,因为它们在一个相当大的库中使用,我不想修改它。

对于我问题的 com 部分,使用 !htrace -diff 我发现由 msxml 分配但在函数调用结束后未释放的线程句柄,它们是否与泄漏有关或者它们会在以后关闭?

感谢所有这些评论,虽然问题仍然存在,但他们帮助我更好地理解了它。

最佳答案

进程可用的虚拟内存是 4Gb 地址空间中的 2Gb。默认情况下,每个 Thread 为其堆栈空间预留大约 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 个工作线程中的每一个都在做某事而不是在完成工作后退出。

关于c++ - _beginthreadex 内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1775822/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com