【发布时间】:2015-03-15 00:44:59
【问题描述】:
我发现我的程序在某个时候发生了泄漏,并创建了完整的内存转储 (.mdmp) 以使用 WinDbg 进行分析。
内存泄漏的主要原因是强句柄。
0:000> !gcroot 02dc02d4
HandleTable:
000b7000 (strong handle)
-> 114e3174 MyApp.Controls.Forms.TransparentOverlappingForm
-> 114e32b8 System.Windows.Forms.PropertyStore
-> 114e39dc System.Windows.Forms.PropertyStore+ObjectEntry[]
-> 02dc03a4 MyApp.Editor.Main.EditorForm
-> 02dc05cc System.ComponentModel.EventHandlerList
-> 114e3884 System.ComponentModel.EventHandlerList+ListEntry
-> 114bef3c System.ComponentModel.EventHandlerList+ListEntry
-> 114bef28 System.ComponentModel.EventHandlerList+ListEntry
-> 02dc0740 System.ComponentModel.EventHandlerList+ListEntry
-> 02dc0630 System.ComponentModel.EventHandlerList+ListEntry
-> 02dc05fc System.ComponentModel.EventHandlerList+ListEntry
-> 02dc05dc System.EventHandler
-> 02dc02d4 MyApp.Editor.Main.EditorLoad
TransparentOverlappingForm 是一种覆盖在另一个控件上的表单,用作控件,以完全支持透明度(这是另一个故事)。 就是这样使用的
TransparentOverlappingForm.Show((Control)OverlapsOn);
TransparentOverlappingForm、EditorForm、TransparentOverlappingForm 重叠的控件 - 都被关闭(如果它是表单)并被释放。
有一个泄漏,只是因为没有收集到 TransparentOverlappingForm,并且内部保存了指向 EditorForm 的链接。
那么如何查看有关“000b7000(强句柄)”的一些信息,以弄清楚,我该如何 GC 呢?
我知道GC强句柄可以是静态变量,但是我怎么知道它是不是静态变量,又在哪里呢。
【问题讨论】:
-
事件是导致此类“泄漏”的好方法,在 C# 中很容易被忽视,您不仅将委托指向方法,而且还添加对实现事件的对象的引用处理程序。通常是设计缺陷,应该是回调。或者使用静态事件。或者只是需要明确取消订阅。一些程序员使用大锤并应用“弱事件模式”。我们看不到你做错了。
标签: c# .net winforms memory-leaks