Memory Leak / Form not being garbage collected
I'm tracking down a Memory leak within an MDI application. Opening, and then closing the form results in the form staying in memory. Using Ant's memory profiler, I can get the following graph of references keeping the form in memory.
I have removed any and all events we attach to the combo controls when Dispose fires on the form.
Can anyone direct me towards a solution?
The C1 namespace comes from ComponentOne.
I should note that I have attempted to see what the c, r, b etc methods on the C1Combo control are via reflector, but its 开发者_如何学运维obviously been run through an obfusticator which makes things difficult to understand.
This reminds me of a huge C# WinForm app I built upon .NET 1.1 years ago. I used .NET Memory Profiler, and boy did it help me find the parasite. Ant's MP probably can do so.
Anyway in my case, I had a lot of parallel threads and timers being created during the usage. The culprit turned out to be a timer instance which was never disposed off properly and hence never ending the spawned thread that the timer is running from.
Not that I can provide you with an answer directly, but if you happened to have threads spawning all over, do watch/handle them with intensive care, especially the stuff running in them.
For my case, it's more of a memory-retention or though most will argue it's just another memory-leak.
If the source of the problem comes from a 3rd party component, well I guess you have to hunt them down.
Good luck in your pursue of the leak culprit!
C1 might have a bug by not releasing an internal reference. Contact the company or search their knowledgebase.
With a different set of 3rd-party components, I remember Telerik controls having bugs that we reported back, and those things were fixed in the next release - sometimes they provided an immediate workaround.
Tracked it down to an internal reference to controls in the C1Combo. There is a list that for some reason has references to the forms and a few other things. In Dispose() on the form, I call this function against each C1Combo control. No idea on the consequences, likely minimal as the control should be Disposed anyway.
It's also very fragile, as if they release a new version, and the obfustication messes up all the method/field names, it will break.
private void RemoveInternalC1ComboReferenceListHack(C1Combo combo)
{
var result = typeof(C1Combo).GetField("_dropDownList", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(combo);
var result2 = result.GetType().GetField("c", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(result);
var result3 = result2.GetType().GetField("r", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(result2);
var result4 = result3.GetType().GetField("b", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(result3);
((System.Collections.Generic.List<Control>)result4).Clear();
}
精彩评论