【问题标题】:Memory Leak / Form not being garbage collected内存泄漏/表单没有被垃圾收集
【发布时间】:2010-12-15 16:43:30
【问题描述】:
我正在跟踪 MDI 应用程序中的内存泄漏。打开,然后关闭表单会导致表单保留在内存中。使用 Ant 的内存分析器,我可以获得以下将表单保存在内存中的引用图。
当 Dispose 在表单上触发时,我已经删除了我们附加到组合控件的所有事件。
谁能指导我找到解决方案?
C1 命名空间来自 ComponentOne。
我应该注意到,我试图通过反射器查看 C1Combo 控件上的 c、r、b 等方法是什么,但它显然是通过一个混淆器运行的,这使得事情变得难以理解。
【问题讨论】:
标签:
c#
memory
memory-leaks
componentone
【解决方案1】:
这让我想起了 1.1 年前我在 .NET 上构建的一个巨大的 C# WinForm 应用程序。我用了.NET Memory Profiler,男孩帮我找到了寄生虫。 Ant 的 MP 应该可以做到。
无论如何,我在使用过程中创建了很多并行线程和计时器。罪魁祸首原来是一个定时器实例,它从未被正确处理,因此永远不会结束运行定时器的衍生线程。
并不是说我可以直接为您提供答案,但如果您碰巧到处都有线程产生,请仔细观察/处理它们,尤其是其中运行的东西。
就我而言,这更像是一种记忆保留,或者尽管大多数人会认为这只是另一种记忆泄漏。
如果问题的根源来自第 3 方组件,那么我想你必须追捕他们。
祝你追查泄密罪魁祸首!
【解决方案3】:
追踪到对 C1Combo 中控件的内部引用。有一个列表由于某种原因引用了表格和其他一些东西。在表单上的 Dispose() 中,我针对每个 C1Combo 控件调用此函数。不知道后果,可能是最小的,因为无论如何都应该处置控件。
它也很脆弱,好像他们发布了一个新版本,混淆了所有的方法/字段名称,它会崩溃。
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();
}