我正在分析“OutofMemory”异常的 .dmp 文件。对象在内存中停留的时间很长,那么有没有一个命令可以检查垃圾收集是否是通过使用 SOS.dll 或 SOSEX 触发的?
问问题
464 次
1 回答
0
在您提到的评论中
当我查看转储时,我看到停留在第 2 代的特定对象几乎占用了 500+ MB,所以我想检查垃圾收集是否运行。
如果您在 Gen 2 中有一个对象,那么垃圾收集至少运行了 2 次,否则它将在 Gen 0 中。
现在您知道了,很明显这些信息并没有真正的帮助。你想知道为什么它会留在内存中。
要找出哪个引用将大对象保留在内存中,请使用 SOS 命令!gcroot
。当您知道这一点时,请查看您的代码以找出此类引用来自何处或应从何处删除。
如果不再有引用,则该对象可能很快就会被释放并且它只是活着,因为此后没有发生第 2 代垃圾回收。请参阅IDisposable 上的这个很好的答案,其中讨论了释放大对象的要点。
在您的情况下,甚至可以GC.Collect()
在释放引用后调用。通常你不应该篡改垃圾回收,但如果你总是有这么大的对象,并且你肯定知道不再需要这个对象并GC.Collect()
解决了 OOM 异常,那么这样做是正确的。
于 2015-10-16T12:45:04.147 回答