- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我目前正在调试一个多线程应用程序,它运行时没有错误,直到某些函数被调用了大约 2000 次。之后应用程序停止响应,我可以追踪到 _beginthreadex 因内存不足错误而失败。
在 ProcessExplorer 中检查应用程序时,我可以看到越来越多的线程句柄泄漏和不断增加的虚拟内存,直到错误发生,私有(private)字节保持低位。泄漏的线程也调用 CoInitialize 而从不调用 CoUninitialize。
我想知道的是:
我希望我的问题很清楚并且不会违反任何规则,这是我的第一个问题,英语不是我的第一语言。:-(
我忘了说,一旦线程终止,我就会关闭 _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/
要定义我的头文件中的线程: class HttpClient { public: ... unsigned int __stdcall PerformLogin(void*);
下面的代码是我的整个测试程序。每次我按 ENTER 时,进程使用的 RAM 都会增加 4k(它会不断增加,不会停止;我在任务管理器中看到它)。怎么了? _beginthread 也会发生同样的事情。
如何创建静态成员函数的线程例程 class Blah { static void WINAPI Start(); }; // .. // ... // .... hThread = (HAND
我目前正在调试一个多线程应用程序,它运行时没有错误,直到某些函数被调用了大约 2000 次。之后应用程序停止响应,我可以追踪到 _beginthreadex 因内存不足错误而失败。 在 Process
是否可以向 beginthreadex 传递多个参数? 我知道我可以创建一个类或结构,但如果我有不相关的数据片段我不想合并到一个类或结构中怎么办? Boost 库似乎允许多个参数,但我该如何为标准 c
我正在尝试使用 _beginthreadex 进行一些基本的并行化,并按照我给出的示例传递参数,但它不起作用。 有什么想法吗? #include #include void MyThread(vo
我不确定我是否以正确的方式解决这个问题,但我正在使用 C++ 和 Visual Studio 2013 中的成员函数和线程。 我发现的其他答案说我必须将我的成员函数转换为静态函数,这样我就可以创建该线
我有点困惑为什么 _beginthreadex() 没有启动我的线程。基本上,我有一个线程: 编辑 #3 -- 添加了 while() 作为我代码的一部分,但我最初从未声明过,因此该线程必须始终运行,
我想将 HANDLE 和 HWND 变量传递给 _beginthreadex 函数,我不想将这些变量设置为全局变量。 这就是我试过的: int APIENTRY WinMain(HINSTANCE h
我用分析器检查了一个项目的源代码。我是 C++ 新手。 它告诉我应该使用 Use _beginthreadex/_endthreadex 函数而不是 CreateThread/ExitThread 函
我有一个丑陋的 C 代码(我是 Windows 下 C 的新手)不要评判我......我想让它成为多线程,它从我的网络服务器列表中读取并检查它们是否存在,因为牢度我需要它是多线程的。搜索了很多谷歌和
大家好,这是我的代码 #include "StdAfx.h" #include #include #include unsigned int __stdcall threadproc(void
我最近了解到 ::_beginthreadex() 总是优于 ::CreateThread(),所以我更改了所有使用 ::CreateThread 的调用()。 唯一的缺点是我不再在 Visual S
我正在尝试将项目从 VS2008 转换为 VS2013,我遇到的(众多)问题之一是: c:\program files (x86)\microsoft visual studio 12.0\vc\at
我有一堆 QWebViews 渲染到一个小部件上。有一点我开始收到错误 QThread::start: Failed to create thread (The access code is inva
所以我制作了一个函数来打印跨不同窗口分层的文本,我希望它在一个单独的线程中,这样我就可以运行一个计时器来显示文本,同时让用户保持打开状态以继续使用该程序。但是,当我编译时出现此错误: error C2
#include #include #include //#include "windowstate.cpp" //DWORD WINAPI MyThreadFunction( LPVOID l
我试图了解 CreateThread 和 _beginthreadex 之间的区别,以及为什么调用 DisableThreadLibraryCalls 只会阻止使用 安装的线程_beginthread
我对使用从 _beginthreadex() 返回的句柄不感兴趣。立即对其调用 CloseHandle() 是否安全? 我认为必须这样做以避免内存泄漏。 最佳答案 是的,您可以在决定不再需要该句柄后立
我正在尝试将一些代码移植到 64 位,但似乎 _beginthreadex 中的线程 address 标识符是 unsigned int这是 32 位的,我无法从函数传递/接收 64 位的 addre
我是一名优秀的程序员,十分优秀!