为什么我的 Windows 控制台应用程序在空闲时会泄漏? (为什么确凿的证据指向kernel32.dll?)
我有一个 Windows 多线程控制台应用程序,似乎每分钟左右泄漏大约 4kb 私有内存。
为了定位泄漏,我逐渐挂起应用程序中的每个线程,直到泄漏停止,令我惊讶的是,罪魁祸首似乎是一个名为“Win32Thread”的线程。
它看起来不像是我明确启动的线程。
如果我附加并破坏应用程序,堆栈跟踪将如下所示:
ntdll.dll!_KiFastSystemCallRet@0()
ntdll.dll!_NtCancelTimer@8() + 0xc bytes
ntdll.dll!_RtlpResetTimer@12() + 0x15 bytes
> ntdll.dll!_RtlpServiceTimer@12() + 0xfd bytes
ntdll.dll!_KiUserApcDispatcher@16() + 0x25 bytes
kernel32.dll!_BaseThreadStart@8() + 0x34 bytes
有谁知道为什么会突然泄漏?
该应用程序在 Win2k3 SP2 双核系统上运行了大约 40 小时。
任何想法都将不胜感激。
I have a windows multi-threded console application that appears to be leaking approximately 4kb private memory every minute or so.
In an effort to localise the leak, I have gradually suspended each thread in the application until the leak stopped, and to my surprise the culprit seems to be a thread named "Win32Thread".
It does not look like a thread I have explicitly started.
If I attach and break the application, the stack trace looks like this:
ntdll.dll!_KiFastSystemCallRet@0()
ntdll.dll!_NtCancelTimer@8() + 0xc bytes
ntdll.dll!_RtlpResetTimer@12() + 0x15 bytes
> ntdll.dll!_RtlpServiceTimer@12() + 0xfd bytes
ntdll.dll!_KiUserApcDispatcher@16() + 0x25 bytes
kernel32.dll!_BaseThreadStart@8() + 0x34 bytes
Does anyone have any idea why this would suddenly leak?
The application as been running for about a 40hrs on a Win2k3 SP2 dual core system.
Any ideas are greately appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
该堆栈跟踪看起来像是在与计时器相关的代码中。我猜您的代码(或您使用的库)通过使用
timeSetEvent
或类似的函数启动了计时器。在这种情况下,泄漏可能发生在您的计时器回调函数中。启动多媒体计时器会导致创建一个线程,并且将从该线程调用您的回调。周期性计时器可以解释为什么它在空闲时泄漏。
That stack trace looks like it's in code related to timers. I'd guess that your code (or a library you use) started a timer by using
timeSetEvent
or a similar function. In that case, the leak would probably be in your timer callback function.Starting a multimedia timer causes a thread to be created, and your callback will be called from that thread. A periodic timer would explain why it leaks while idling.
您的应用程序是否有任何 APC(异步过程调用)或计划的计时器事件?
多媒体计时器回调会。
如果您的回调使用 C 运行时调用,这些调用会进行一次性线程本地分配(惰性地,在线程中第一次调用函数时分配)来完成其工作(_tcstol、sprintf 等)。由于线程不是使用 beginthread() 或 beginthreadex() 启动的,因此当线程终止时,无法清理该内存,因此这将表现为泄漏。
Does your application have any APCs (Asynchronous procedure calls) or scheduled timer events?
Multimedia timer callbacks would.
If your callback uses C runtime calls, these calls makes one-off thread local allocations (lazily, allocated first time the function is called in a thread) to do their work (_tcstol, sprintf etc). Because the thread was not started with beginthread() or beginthreadex() this memory can't be cleaned up when the thread dies, so that would manifest as a leak.