我目前正在调试一个大型的Winforms应用程序,它有一些内存泄漏问题。我使用.NET内存分析器,到目前为止,我已经能够找到其中的一些漏洞并解决它们。但现在我面临着一个问题,我不确定这是一个问题,如果它是一个问题,我不知道如何解决它。
在运行我的应用程序大约1分钟后(考虑到普通用户可能会使用它几个小时,这并不是很多),.NET内存分析器显示了大约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本身保留了对我的控件的引用,从而导致一些内存没有被释放(如果它是用于保持对象池或类似东西的有限数量的内存,这可能是正常的,但如果它是一个不受控制的内存泄漏,则可能是一个问题)?如果它不是来自克利普顿,你有办法正确地销毁这些实例吗?
非常感谢!
编辑:
我只是注意到KryptonButtonEx类并不是来自于克利普顿,而是来自我的应用程序。但我不认为它对问题有任何改变,因为它唯一做的就是覆盖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);
}
}
}
发布于 2011-05-27 21:08:46
你发布了错误的代码。您应该对移除按钮的代码非常感兴趣,而不是创建按钮的代码。搜索Controls.Remove和Controls.Clear,并确保要删除的每个控件都已被释放。另一个诊断是TaskMgr.exe,Processes选项卡。查看+选择列并勾选用户对象。看到这个数字稳步上升是一个明确的线索,表明代码没有在应该部署控件的地方部署控件。这是我所知道的唯一不调用Dispose()导致永久泄漏的情况。
不使用Controls.Clear(),而使用如下代码:
while (panel.Controls.Count > 0) panel.Controls[0].Dispose();
释放控件还会自动将其从父级的Controls集合中移除。
https://stackoverflow.com/questions/6151867
复制相似问题