【问题标题】:.net WinDbg strong handle leak.net WinDbg 强句柄泄露
【发布时间】: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


【解决方案1】:

啊,像往常一样,当我问别人问题时,我会在这之后解决它。

我用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).

【讨论】:

    猜你喜欢
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    相关资源
    最近更新 更多