我有一个创建节点树的应用程序,然后抛出它们并创建新树。
应用程序在启动时分配大约20 MB。但我尝试多次加载大型节点文件,分配的内存超过700 MB。我以为我会看到垃圾收集器有时会释放内存。
我所使用的机器有12 GB的RAM,所以可能只是分配了这么少的“小”内存并不重要。
我已经找到了很多关于GC如何工作的好信息,并且最好不要告诉它该做什么。但是我想验证它实际上是在做什么,而且我不会在代码中做错什么来防止我的对象被清除。
答案 0 :(得分:7)
当以下任何一种情况发生时,GC通常会运行:
还有其他一些场景,但我现在暂时不会这样做。
您没有告诉我们您如何衡量内存使用情况,但如果您正在查看进程本身的内存使用情况(例如通过任务管理器),那么您可能看不到预期的数字。请记住,.NET运行时本质上有自己的内存管理器,可以代表您管理的应用程序处理内存使用情况。运行时尝试对它很聪明,因此它不会一直为操作系统分配和释放内存(这些操作很昂贵)。 This question也可能相关。
如果您担心内存泄漏,请查看some of the answers here。
答案 1 :(得分:2)
答案 2 :(得分:2)
.Net 3.5垃圾收集器什么时候运行? 我以为我会看到垃圾收集器有时会释放内存。
由于GC是非确定性的,因此您无法确定何时发布集合。简答:它会在需要时运行。试图分析你的代码并预测或假设它应该在某个特定的时间运行通常会导致一个兔子洞。
答案 3 :(得分:2)
您可能拥有内存泄漏的托管等效项。您是否维护对这些对象的陈旧引用(即,您是否有List<T>
或其他跟踪这些节点的对象?
是否订阅了一个不超出范围的对象事件?保留对事件订阅的引用,因此如果不分离它将使对象保持活动状态。
您可能还忘记了Dispose
实施IDisposable
的对象。不用看你的代码就不能说了。
GC的确切行为是实现定义的。您应该设计您的应用程序,使其无关紧要。如果您需要确定性内存管理,那么您使用的是错误的语言。使用工具(RedGate的ANTS探查器会这样做)来查看你是否在某处泄漏了引用。
答案 4 :(得分:2)
回答:我是否泄漏了物体或GC还不需要运行?
使用内存分析器查看分配了哪些对象。作为基本步骤 - 强制垃圾收集(GC.Collect)并检查分配的内存(GC.GetTotalMemory)是否合理。
答案 5 :(得分:2)
如果您想确保不留下任何不需要的物品,可以使用dotTrace内存分析器。它允许您在内存中拍摄两个对象快照(相隔一段时间)并进行比较。您可以清楚地看到是否有任何旧节点仍然存在,以及是什么保留了它们并阻止它们被收集。
答案 6 :(得分:1)
您可以使用GC.RegisterForFullGCNotification监控.NET 4.0及更高版本中的垃圾收集器活动,如以下链接所述:http://www.abhisheksur.com/2010/08/garbage-collection-notifications-in-net.html