13

我的应用程序(基本应用程序是 MFC 与 C++/CLI 互操作,但它也包含很多 C#、Windows 窗体、WPF)有句柄泄漏。应用程序启动后不久,我可以看到任务管理器中的句柄计数不断增长(以每秒 10 个新句柄的速度)。所以我用handles.exe来看看它们是什么类型的句柄。我发现泄漏的句柄是进程句柄。它们是我的应用程序进程的进程句柄。

所以我想知道哪些操作通常会为其运行的进程创建一个句柄。知道吗?你见过这样的事情吗?考虑到我不能使用调试 DLL 并且我只能使用可以 xcopy 部署的工具,我还能做些什么来追踪泄漏。

更新:

我能够向它抛出windbg!handle, !htrace并发现进程句柄都是使用以下堆栈跟踪创建的(按频率排序):

0x79f7570b: mscorwks!CorExitProcess+0x00022055
0x79f03edd: mscorwks!GetPrivateContextsPerfCounters+0x0000b6fe
0x79f04b87: mscorwks!GetPrivateContextsPerfCounters+0x0000c3a8
0x79f04b03: mscorwks!GetPrivateContextsPerfCounters+0x0000c324
0x79f919bf: mscorwks!CorExitProcess+0x0003e309
0x79f91b28: mscorwks!CorExitProcess+0x0003e472
0x792d6b4c: mscorlib_ni+0x00216b4c
0x1391a663: +0x1391a663
0x1391a0b1: +0x1391a0b1
0x7a9ea544: System_ni+0x005aa544
0x792a842f: mscorlib_ni+0x001e842f

或者

0x7c8106f5: kernel32!CreateThread+0x0000001e
0x79f04bb2: mscorwks!GetPrivateContextsPerfCounters+0x0000c3d3
0x79f04b03: mscorwks!GetPrivateContextsPerfCounters+0x0000c324
0x79f919bf: mscorwks!CorExitProcess+0x0003e309
0x79f91b28: mscorwks!CorExitProcess+0x0003e472
0x792d6b4c: mscorlib_ni+0x00216b4c
0x1391a663: +0x1391a663
0x1391a0b1: +0x1391a0b1
0x7a9ea544: System_ni+0x005aa544
0x792a842f: mscorlib_ni+0x001e842f

或者

0x08ec2eba: +0x08ec2eba
0x792b8277: mscorlib_ni+0x001f8277
0x792b8190: mscorlib_ni+0x001f8190
0x792b8040: mscorlib_ni+0x001f8040
0x792b7ff2: mscorlib_ni+0x001f7ff2
0x677e48f3: System_Runtime_Remoting_ni+0x000748f3
0x677e44be: System_Runtime_Remoting_ni+0x000744be
0x677e46ec: System_Runtime_Remoting_ni+0x000746ec
0x677e8408: System_Runtime_Remoting_ni+0x00078408
0x7926eb8d: mscorlib_ni+0x001aeb8d

现在这告诉我什么?

4

3 回答 3

5

调用堆栈看起来不对。您是否正确设置了符号服务器?.symfix 应该在 Windbg 中发挥作用。之后你应该得到一个更好的堆栈跟踪。

看起来存在此问题的部分代码是托管的,因此在 DuplicateHandle 和 OpenProcess 上中断并将托管调用堆栈转储到那里是有意义的。这两种方法是唯一可以产生真实进程句柄的方法。

您可以像这样声明断点并在断点被命中时执行命令。在这种情况下,打印托管堆栈,然后继续执行。

bp kernel32!OpenProcess "!ClrStack;g"
于 2011-05-08T20:30:58.373 回答
1

通过互操作调用 COM 对象的 Web 服务有同样的问题。

我通过针对我创建的互操作对象显式调用 Marshal.ReleaseComObject 解决了这个问题。在那一刻之后对我来说没有问题。

希望能帮助到你。

于 2011-05-07T14:17:54.087 回答
0

所以......你是否明确地做性能计数器(如果是这样,请尝试禁用它们以缩小泄漏源的范围)。

于 2011-05-07T14:36:22.143 回答