我发现我的程序在某些时候泄漏,并创建了完整的内存转储(.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强句柄可以是一个静态变量,但我怎么能弄清楚它是一个静态变量,它在哪里。
答案 0 :(得分:0)
啊,就像我问某人一个问题一样,我会在此之后解决。
我以hacky方式解决了问题,仍有小漏,由TransparentOverlappingForm引起。
所以问题是开放的。
var propStoreControlField = typeof(Control).GetField("propertyStore", BindingFlags.Instance | BindingFlags.NonPublic);
var propStoreType = propStoreControlField.FieldType;
var propStoreSetObjectMethod = propStoreType.GetMethod("SetObject", new Type[] {typeof(int), typeof(object)});
var intPropStoreFormField = typeof(Form).GetField("PropDialogOwner", BindingFlags.Static | BindingFlags.NonPublic);
propStoreSetObjectMethod.Invoke(propStoreControlField.GetValue(Form), new object[] {intPropStoreFormField.GetValue(null), null});
Form = null;
OverlapsOn = null;
WinDbg的:
0:000> !gcroot 031dcad0
HandleTable:
001f6820 (strong handle)
-> 031dcad0 MyApp.Controls.Forms.TransparentOverlappingForm
Found 1 unique roots (run '!GCRoot -all' to see all roots).