В настоящее время я отлаживаю большое приложение Winforms, у которого есть проблемы с утечкой памяти. Я использую профилировщик памяти .NET и до сих пор мне удавалось найти некоторые из этих утечек и устранить их. Но теперь я столкнулся с проблемой, в которой я не уверен, что это проблема, и если она есть, я не знаю, как ее решить.
После запуска моего приложения в течение примерно 1 минуты (что не так уж много, учитывая, что обычные пользователи могут использовать его часами), профилировщик памяти .NET показывает мне около 100-200 экземпляров различных элементов управления из набора инструментов Krypton, и это число увеличивается, если я продолжаю идти (они никогда не собираются мусором, потому что кажется, что на них все еще есть ссылки). Теперь, если я проверю корневой путь этих экземпляров, и они все будут выглядеть так:
Я не знаю, где искать в моем коде правильную разыменование этих экземпляров, когда они больше не нужны, так как я не знаю, что все еще ссылается на элемент управления. Я знаю место, где создается 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);
Итак, мой вопрос:
Возможно ли, что сам Криптон хранит ссылку на мои элементы управления, что приводит к тому, что некоторая память не освобождается (что может быть хорошо, если это ограниченный объем памяти, используемый для хранения пула объектов или чего-то в этом роде, но это может быть проблема, если это неконтролируемая утечка памяти)? Если это не от Криптона, есть ли у вас идея, где искать правильные уничтожения этих экземпляров?
Большое спасибо!
EDIT:
Я только что заметил, что класс 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);
}
}
}