【问题标题】:How can I tell if the .Net 3.5 garbage collector has run?如何判断 .Net 3.5 垃圾收集器是否已运行?
【发布时间】:2012-02-29 23:43:29
【问题描述】:

我有一个创建节点树的应用程序,然后将它们扔掉并生成新树。

应用程序在启动时分配大约 20 MB。但是我多次尝试加载一个大的节点文件,分配的内存超过了 700 MB。我想我有时会看到垃圾收集器释放内存。

我所在的机器有 12 GB 的 RAM,所以也许只是分配的这么“少量”内存对 GC 来说并不重要。

我找到了很多关于 GC 工作原理的好信息,最好不要告诉它该做什么。但我想验证它是否真的在做任何事情,并且我并没有在代码中做错什么,阻止我的对象被清理。

【问题讨论】:

  • 简短回答:需要时。
  • ^^^ 是的。实施定义了我的朋友。您应该设计您的应用程序,使其无关紧要。如果您需要确定性内存管理,那么您使用的是错误的语言。
  • @BrianRasmussen 这是乐观的观点。我宁愿说只要它愿意这样做。
  • 哇,很多好信息。明天将在工作中回顾所有这些,并为一些答案投票并选择一个。谢谢。
  • 您显然相信 RAM 与内存管理有关的谎言。我向你保证不会。将内存视为磁盘空间RAM 只是一种特殊的芯片,可以让您的磁盘更快。垃圾收集器不关心你有多少内存;它关心你有多少虚拟空间虚拟空间如何映射到物理RAM与垃圾收集器无关;这更多是操作系统的问题。如果您关心内存使用情况了解现代内存管理系统的工作原理

标签: c# .net garbage-collection


【解决方案1】:

GC 通常在以下两种情况发生时运行:

  • 你调用了 GC.Collect(你不应该这样做)
  • Gen0 的预算已用完

还有其他一些场景,但我现在将跳过这些场景。

您没有告诉我们您是如何测量内存使用量的,但如果您正在查看进程本身的内存使用量(例如通过任务管理器),那么您可能看不到您期望的数字。请记住,.NET 运行时本质上具有自己的内存管理器,它代表您托管的应用程序处理内存使用情况。运行时尝试对其进行智能处理,因此它不会一直为操作系统分配和释放内存(这些是昂贵的操作)。 This question 也可能是相关的。

如果您担心内存泄漏,请查看some of the answers here

【讨论】:

  • 我不知道 GC 没有释放到操作系统。这是有道理的,并回答了我的问题。
【解决方案2】:

.Net 3.5 垃圾收集器何时运行?
我想我有时会看到垃圾收集器释放内存。

由于 GC 是非确定性的,因此您不一定能确定它何时发出收集。简短的回答:它会在需要时运行。试图分析您的代码并预测或假设它应该在某个时间运行通常会落入一个兔子洞。

【讨论】:

    【解决方案3】:

    回答:是我泄漏了对象还是 GC 还不需要运行?

    使用内存分析器查看分配了哪些对象。作为基本步骤 - 强制垃圾回收 (GC.Collect) 并检查分配的内存 (GC.GetTotalMemory) 是否合理。

    【讨论】:

      【解决方案4】:

      如果您想确保没有留下任何不需要的对象,您可以使用dotTrace 内存分析器。它允许您拍摄内存中对象的两个快照(分开一段时间)并比较它们。您将可以清楚地看到是否有任何旧节点仍然存在,以及是什么保留了对它们的引用并阻止它们被收集。

      【讨论】:

      • 不知道 dotTrace。谢谢你。
      【解决方案5】:

      您可能有内存泄漏的托管等效项。您是否在维护对这些对象的过时引用(即,您是否有 List<T> 或其他跟踪这些节点的对象)?

      是否订阅了未超出范围的对象的事件?维护了对事件订阅者的引用,因此如果您不分离,它将使您的对象保持活动状态。

      您可能还忘记了实现IDisposable 的对象的Dispose。不能说没有看到你的代码。

      GC 的确切行为由实现定义。您应该设计您的应用程序,使其无关紧要。如果您需要确定性内存管理,那么您使用的是错误的语言。使用工具(RedGate 的 ANTS 分析器可以)查看您是否在某处泄漏了引用。

      【讨论】:

      • 我有 List,但当不再需要其中的数据时,我会清除它们。
      【解决方案6】:

      这部漫画是解释这个话题的最佳方式:)

      【讨论】:

      • 这是一个很好的说明,尽管我更担心知道它是否曾经运行过或者我是否正在泄漏,而不是确切地知道它何时运行并以某种方式在应用程序中使用该信息。
      【解决方案7】:

      您可以使用 GC.RegisterForFullGCNotification 监控 .NET 4.0 及更高版本中的垃圾收集器活动,如以下链接所述:http://www.abhisheksur.com/2010/08/garbage-collection-notifications-in-net.html

      【讨论】:

        猜你喜欢
        • 2011-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-14
        • 1970-01-01
        • 2010-12-21
        • 1970-01-01
        • 2019-10-01
        相关资源
        最近更新 更多