c# – Krypton(Winforms库)是否可能存在内存泄漏问题

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

我正在调试一个大的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);
        }
    }
}

解决方法:

你发布了错误的代码.您应该对删除它的代码非常感兴趣,而不是创建按钮的代码.搜索Controls.Remove和Controls.Clear并确保正在处理要删除的每个控件.另一个诊断是TaskMgr.exe,Processes选项卡.查看选择列并勾选USER对象.看到这个数字稳步上升是一个很难的线索,代码没有处理控制应该在哪里.这是我所知道的唯一不会调用Dispose()导致永久性泄漏的情况.

而不是Controls.Clear(),使用这样的代码:

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

处置控件也会自动将其从父控件集合中删除.

本文标题为:c# – Krypton(Winforms库)是否可能存在内存泄漏问题

基础教程推荐