.Net中的内存泄漏问题

5
我想知道内存是否真的泄漏了。我的情况如下:
  1. 我的 .Net 应用程序占用 x 量的内存。
  2. 我打开了一些对话框,现在它占用了 x+y 量的内存
  3. 关闭所有最近打开的对话框
  4. 仍然占用了 x + Y 的内存
这是内存泄漏还是垃圾回收器没有清除内存的情况。
由于事件也被视为引用,如果事件存在于取消引用的对象中,那么该事件将不被视为引用,对吗?

1
你的问题比较含糊,能否提供更多信息?发布一些代码或者给出一个导致内存泄漏的实际场景。 - Alireza Maddah
只是想知道:即使关闭了打开的对话框,内存仍未被释放,这是否意味着存在内存泄漏,或者可能是内存仍未被垃圾回收的情况? - Make It Perfect
4
分配内存是昂贵的。.NET 应用程序会分配内存,但只有在必要时才会将其返回给系统。停止查看任务管理器;它无法告诉您任何信息。当出现 OOME 时,您就会知道您存在泄漏/内存问题。 - user1228
1
除了Will的评论之外,您还应该尝试多次打开/关闭对话框,以查看消耗是否真的会不断上升。为了确保,您需要像Redgate的ANTS这样的内存分析器。 - Oliver
5个回答

10

垃圾收集器仅释放不再被引用的对象。

它不会神奇地删除所有您不再需要的对象。

检查是否仍然有对任何对象的引用。请记住,事件也被视为引用。(它需要知道要去哪个对象)


2
有好几次我被事件捕捉住了,导致对象无法释放。+1 - Matt Ellen
完全正确。但根据我的了解,垃圾收集器不会立即收集取消引用的对象。仅当应用程序的内存不足时,它才会收集对象。因此,在我的情况下,所有对象可能都已取消引用,但仍未从内存中清除。对吗? - Make It Perfect
这比那要复杂一些。它需要考虑更多的因素。想想看,一个10 Mb的程序不会等到填满4GB才开始释放。它不会只是等待内存用尽。 - Yochai Timmer
制作一个简单的测试按钮,创建对象,然后超出范围运行。点击几次,看看内存是否持续增加(不应该)。 - Yochai Timmer
还有一个问题:由于事件也被视为引用,如果事件存在于取消引用的对象中,那么该事件将不被视为引用,对吗? - Make It Perfect
1
好的,发现内存泄漏是通过一些事件和甚至一些对象泄漏的。谢谢大家。 - Make It Perfect

2

内存只有在需要时才会进行垃圾回收,当所谓的第0代满或整个系统内存压力足够强制进行垃圾回收时,就会进行更多技术性的操作。当内存超出范围时,不会自动回收。更多信息在这里在这里

仅供测试,在关闭对话框后(不再引用之后),尝试调用GC.Collect()来强制GC收集任何可用内存。

实际上,您不应该操纵垃圾回收器,它已经被严格优化以获得最佳性能。

如果您怀疑确实存在内存泄漏,请使用某种内存分析工具来分析您的应用程序。

例如,尝试使用RedGates Memory Profiler,他们有一个基于时间的试用版。
按照这个操作指南,快速了解并学习一些要查找和如何查找。


1
在 .Net 中,一旦您不引用一个对象,该对象就会被回收。如果您有一个活动的引用,则该对象将保持活动状态。因此,要查找内存泄漏,您需要执行以下操作:
  1. 查找对象列表和占用的内存
  2. 确定您怀疑应该已经释放的对象。
  3. 查找持有此对象的根源。
  4. 修复根源。

您可以使用某些内存分析器或使用WinDbg+sos来完成此操作。人们认为windbg难以使用,但对于这些情况,windbg+sos更易于使用,并且它是免费的。修复泄漏后,您会感到高兴。您将成为那些始终喜欢免费强大工具的人之一。

请查看此链接。

http://blogs.msdn.com/b/ricom/archive/2004/12/10/279612.aspx

http://blogs.msdn.com/b/delay/archive/2009/03/11/where-s-your-leak-at-using-windbg-sos-and-gcroot-to-diagnose-a-net-memory-leak.aspx


0

你可以尝试使用内存分析工具,例如JetBrains dotTrace,来分析你的应用程序的内存使用情况。


-1

可能是垃圾收集器没有清除内存的情况


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接