現在、メモリ リークの問題がある大きな 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);
だから私の質問は:
クリプトン自体が私のコントロールへの参照を保持していて、一部のメモリが解放されていない可能性はありますか (オブジェクト プールなどを保持するために使用されるメモリ量が限られている場合は問題ありませんが、次の場合は問題になる可能性があります)。それは制御されていないメモリリークです)?クリプトンから来ていない場合、それらのインスタンスを正しく破壊するためにどこを探すべきか考えていますか?
どうもありがとう!
編集:
クラス 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);
}
}
}