内存泄漏/表单未被垃圾收集

发布于 2024-08-10 21:20:08 字数 322 浏览 4 评论 0原文

我正在追踪 MDI 应用程序中的内存泄漏。打开然后关闭该表单会导致该表单保留在内存中。使用 Ant 的内存分析器,我可以获得以下将表单保留在内存中的引用图。

当在窗体上触发 Dispose 时,我已删除附加到组合控件的所有事件。

谁能指导我找到解决方案?

C1命名空间来自ComponentOne。

我应该注意,我试图通过反射器查看 C1Combo 控件上的 c、r、b 等方法,但它显然是通过混淆器运行的,这使得事情难以理解。

Ant 的参考图

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.

Ant's Reference Graph

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

全部不再 2024-08-17 21:20:08

这让我想起了几年前我在 .NET 1.1 上构建的一个巨大的 C# WinForm 应用程序。我使用了 .NET Memory Profiler,它确实帮助我找到了寄生虫。 Ant的MP或许可以做到。

无论如何,就我而言,我在使用过程中创建了很多并行线程和计时器。罪魁祸首原来是一个计时器实例,它从未被正确处理过,因此永远不会结束计时器运行的生成线程。

我不能直接为您提供答案,但如果您碰巧到处都有线程产生,请务必仔细观察/处理它们,尤其是其中运行的内容。

就我而言,这更多的是一种记忆保留,或者尽管大多数人会认为这只是另一种记忆泄漏。

如果问题的根源来自第三方组件,那么我想您必须追查它们。

祝您追查泄密罪魁祸首!

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!

爱情眠于流年 2024-08-17 21:20:08

C1 可能因未释放内部引用而存在错误。 联系该公司或搜索其知识库

使用一组不同的 3rd 方组件,我记得 Telerik 控件存在我们报告的错误,这些问题在下一个版本中得到了修复 - 有时它们提供了立即的解决方法。

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.

╭⌒浅淡时光〆 2024-08-17 21:20:08

追踪到 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();
    }

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();
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文