我正在追踪 MDI 应用程序中的内存泄漏。打开,然后关闭表单会导致表单保留在内存中。使用 Ant 的内存分析器,我可以获得以下将表单保存在内存中的引用图。
当 Dispose 在表单上触发时,我已经删除了我们附加到组合控件的所有事件。
任何人都可以指导我寻求解决方案吗?
C1 命名空间来自 ComponentOne。
我应该注意,我试图通过反射器查看 C1Combo 控件上的 c、r、b 等方法是什么,但它显然是通过一个混淆器运行的,这使得事情变得难以理解。
我正在追踪 MDI 应用程序中的内存泄漏。打开,然后关闭表单会导致表单保留在内存中。使用 Ant 的内存分析器,我可以获得以下将表单保存在内存中的引用图。
当 Dispose 在表单上触发时,我已经删除了我们附加到组合控件的所有事件。
任何人都可以指导我寻求解决方案吗?
C1 命名空间来自 ComponentOne。
我应该注意,我试图通过反射器查看 C1Combo 控件上的 c、r、b 等方法是什么,但它显然是通过一个混淆器运行的,这使得事情变得难以理解。
这让我想起了 1.1 年前我在 .NET 上构建的一个巨大的 C# WinForm 应用程序。我使用了.NET Memory Profiler,男孩帮我找到了寄生虫。Ant 的 MP 可能可以这样做。
无论如何,就我而言,我在使用过程中创建了很多并行线程和计时器。罪魁祸首原来是一个计时器实例,它从未被正确地关闭,因此永远不会结束计时器正在运行的衍生线程。
并不是说我可以直接为您提供答案,但是如果您碰巧到处都有线程产生,请仔细观察/处理它们,尤其是其中运行的东西。
就我而言,这更像是一种记忆保留,或者尽管大多数人会认为这只是另一种记忆泄漏。
如果问题的根源来自第 3 方组件,那么我想您必须追捕它们。
祝您追查泄密罪魁祸首!
C1 可能会因不释放内部引用而出现错误。联系公司或搜索他们的知识库。
使用一组不同的第 3 方组件,我记得 Telerik 控件存在我们报告的错误,并且这些问题在下一个版本中得到修复 - 有时它们提供了直接的解决方法。
将其追踪到对 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();
}