【问题标题】:Is it possible that Krypton (Winforms library) has memory leak issues氪(Winforms 库)是否有可能存在内存泄漏问题
【发布时间】:2011-09-03 08:35:30
【问题描述】:

我目前正在调试一个存在一些内存泄漏问题的大型 Winforms 应用程序。我使用 .NET 内存分析器,到目前为止,我已经能够找到其中的一些泄漏并解决它们。但是现在我面临一个问题,我不确定是不是问题,如果是问题,我不知道如何解决。

在运行我的应用程序大约 1 分钟后(考虑到普通用户可以使用几个小时,这并不算多),.NET 内存分析器向我显示了来自 Krypton Toolkit 的不同控件的大约 100-200 个实例,这个数字是如果我继续前进,则会增加(它们永远不会被垃圾收集,因为看起来它们仍在某处被引用)。现在,如果我检查这些实例的根路径,它们看起来都像:

我不知道在我的代码中哪里可以在不再需要这些实例时正确地取消引用它们,因为我不知道什么仍在引用该控件。我知道创建 KryptonButtonEx 的位置,据我所知,ViewManager 是由这个按钮创建的,但我仍然不知道我能做些什么。对于那些感兴趣的人,创建按钮的代码是这样的:

        KryptonButton newControlButton = new KryptonButton();
        newControlButton.Tag = mtActivityControl;
        newControlButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
        newControlButton.AutoSize = true;
        newControlButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
        newControlButton.ButtonStyle = ComponentFactory.Krypton.Toolkit.ButtonStyle.ListItem;
        newControlButton.Location = new System.Drawing.Point(3, 3);
        newControlButton.Name = string.Format("controlButton{0}", mtActivityControl.SymbolicName);
        newControlButton.Size = new System.Drawing.Size(96, 23);
        newControlButton.StateCommon.Content.Image.ImageH = ComponentFactory.Krypton.Toolkit.PaletteRelativeAlign.Near;
        newControlButton.StateCommon.Content.ShortText.TextH = ComponentFactory.Krypton.Toolkit.PaletteRelativeAlign.Near;
        newControlButton.TabIndex = 5;

        StringBuilder buttonText = new StringBuilder();
        buttonText.Append(Path.GetFileName(mtActivityControl.ControlName));
        /*if (mtActivityControl.SymbolicName.Length != 0)
        {
            buttonText.Append(" (");
            buttonText.Append(mtActivityControl.SymbolicName);
            buttonText.Append(")");
        }*/

        newControlButton.Text = buttonText.ToString();
        newControlButton.Values.ExtraText = "";
        newControlButton.Values.Image = null;
        newControlButton.Values.ImageStates.ImageCheckedNormal = null;
        newControlButton.Values.ImageStates.ImageCheckedPressed = null;
        newControlButton.Values.ImageStates.ImageCheckedTracking = null;
        newControlButton.Values.Text = buttonText.ToString();
        newControlButton.Click += new System.EventHandler(this.controlsButton_Click);

尽管我的研究告诉我没有必要,但我还是在 Dispose 函数中解开了这样的事件:

newControlButton.Click -= new System.EventHandler(this.controlsButton_Click);

所以我的问题是:

Krypton 本身是否有可能保留对我的控件的引用,这导致一些内存没有被释放(如果它是用于保留对象池或类似东西的有限内存量,这可能是可以的,但可能是如果它是一个不受控制的内存泄漏问题)?如果它不是来自 Krypton,您是否知道在哪里可以正确销毁这些实例?

非常感谢!

编辑:

我刚刚注意到 KryptonButtonEx 类不是来自 Krypton,而是来自我的应用程序。但我认为它不会改变任何问题,因为它所做的唯一事情就是覆盖 GetPreferredSize 函数:

/// <summary>
/// An extended/fixed KryptonButton which handles resizing correctly.
/// </summary>
public class KryptonButtonEx : ComponentFactory.Krypton.Toolkit.KryptonButton
{
    /// <summary>
    /// Gets the size of the preferred.
    /// </summary>
    /// <param name="proposedSize">Size of the proposed.</param>
    /// <returns></returns>
    public override Size GetPreferredSize(Size proposedSize)
    {
        // Do we have a manager to ask for a preferred size?
        if (ViewManager != null)
        {
            // Ask the view to peform a layout
            Size retSize = ViewManager.GetPreferredSize(Renderer, proposedSize);

            // Apply the maximum sizing
            if (MaximumSize.Width > 0) retSize.Width = Math.Min(MaximumSize.Width, retSize.Width);
            if (MaximumSize.Height > 0) retSize.Height = Math.Min(MaximumSize.Height, retSize.Width);

            // Apply the minimum sizing
            if (MinimumSize.Width > 0) retSize.Width = Math.Max(MinimumSize.Width, retSize.Width);
            if (MinimumSize.Height > 0) retSize.Height = Math.Max(MinimumSize.Height, retSize.Height);

            return retSize;
        }
        else
        {
            // Fall back on default control processing
            return base.GetPreferredSize(proposedSize);
        }
    }
}

【问题讨论】:

  • 你为什么不问问 Krypton Toolkit 的开发者?如果有人知道,那就是他们。
  • 我查看了论坛,似乎没有人谈论这个问题。我会马上发布一个问题,虽然我不知道为什么我没有考虑过;)。

标签: c# winforms memory-leaks krypton


【解决方案1】:

您发布了错误的代码。而不是创建按钮的代码,你应该对删除它的代码非常感兴趣。搜索 Controls.Remove 和 Controls.Clear 并确保正在释放每个要删除的控件。另一个诊断是 TaskMgr.exe,进程选项卡。查看 + 选择列并勾选 USER 对象。看到这个数字稳步上升是一个硬线索,表明代码没有将控件配置在应该的位置。这是我所知道的唯一不调用 Dispose() 导致永久泄漏的情况。

使用如下代码代替 Controls.Clear():

 while (panel.Controls.Count > 0) panel.Controls[0].Dispose();

释放控件也会自动将其从父控件集合中移除。

【讨论】:

  • 事实上我可以在任务管理器中看到 USER 对象不断上升。对于删除按钮的代码,执行类似 if (components != null)) { components.Dispose(); }
  • (对不起,误按了输入)...自动执行所有操作以正确清洁按钮?
  • 好吧,你找到了。处置组件还不够好,您必须处置控件。使用代码 sn-p 更新帖子。
  • 这样解决了,非常感谢! :) 实际上,Controls 字段似乎并不包含我必须处理的所有内容,但是如果我在控件中的每个按钮上手动调用 Dispose,它就不会再泄漏了。
猜你喜欢
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 2014-03-09
  • 2018-11-26
  • 2012-09-27
相关资源
最近更新 更多