Is it possible that Krypton (Winforms library) has memory leak problems?

I am currently debugging a large Winforms application that caused some memory leak problems. I use the .NET memory profiler, and so far I have been able to find some of these leaks and solve them. But now I am faced with a problem that I am not sure is a problem, and if it is one, I do not know how to solve it.

After launching my application for 1 minute (which is not so much, considering that ordinary users can use it for several hours), the NET memory profiler shows me about 100-200 copies of various controls from the Krypton Toolkit, and this is the number if I I’ll continue (they’re never going to garbage, because they seem to be still mentioned somewhere). Now, if I check the root path of these instances, and they all look like this:

Root path for Krypton ViewManager

I don’t know where to look in my code so that these instances are correctly edited when they are no longer needed, because I don’t know what is still referring to the control. I know the place where KryptonButtonEx is created, and from what I understand, the ViewManager is created by this button, but still I don’t see what I can do about it. For those interested, the code for creating the button is as follows:

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); 

and even if this is not necessary from what my research told me, I canceled this event in the Dispose function:

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

So my question is:

Is it possible that Krypton itself maintains a link to my controls, which leads to the fact that some memory is not freed up (which may be good if it is a limited amount of memory used to store a pool of objects or something like that, but it can to be a problem if this is an uncontrolled memory leak)? If this does not come from Krypton, do you have an idea how to properly search for these instances?

Thank you very much!

EDIT:

I just noticed that the KryptonButtonEx class does not come from Krypton, but from my application. But I don’t think this changes anything in the question, since the only thing he does is to override the GetPreferredSize function:

 /// <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); } } } 
+4
source share
1 answer

You sent the wrong code. Instead of the code that creates the button, you should be very interested in code that removes it. Find Controls.Remove and Controls.Clear and make sure that every control that is deleted is deleted. Another diagnostic is the TaskMgr.exe tab, Processes. Open + Select columns and mark USER objects. Seeing that this number is growing steadily, it is difficult to understand that the code does not control the controls where necessary. This is the only time that I know that you are not calling Dispose (), causing a persistent leak.

Instead of Controls.Clear (), use the following code:

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

Removing a control also automatically removes it from the parent control collection.

+5
source

All Articles