【问题标题】:Efficient Garbage Collection高效垃圾收集
【发布时间】:2013-12-19 11:36:27
【问题描述】:

考虑以下对象

class someObject;
{
   public objectA A{get;set;}
   public objectB B{get;set;}
   public objectC C{get;set;}
   public objectD D{get;set;}
   //...
}

在某些时候,ObjectD 不再需要,但someObject 的实例仍然存在,并且会持续几个小时,objectD 占用了大量内存,所以在它的角色完成后我确实将它设置为空。

  • 这是否意味着内存将立即从ObjectD 中释放出来? 我把它设置为空?
  • 如果一个对象在某个范围内长时间未使用,.NET 会做什么 关于它?

【问题讨论】:

    标签: c# garbage-collection


    【解决方案1】:

    这是否意味着一旦我设置了内存就会从 ObjectD 中释放出来 它为空?

    它不是对象集null - 它对内存中对象的引用设置为null。并且对象将一直存在,直到垃圾收集器收集它(如果您没有对该对象的任何其他引用)。

    看看Fundamentals of Garbage Collection

    【讨论】:

    • 所以垃圾收集器在没有更多引用时收集它?有没有办法让 GC 对某个对象立即采取行动?
    • 请注意,垃圾收集器的习惯实际上是不同的,具体取决于您选择的构建配置。发布版本在修剪未使用的对象方面更具侵略性
    • @user1492051 你可以手动运行垃圾收集,但这是相当昂贵的操作,它会影响应用程序中的所有垃圾对象,而不仅仅是这个
    • @user1492051 查看我对其他问题之一的评论 - 确实可以强制收集,但这通常弊大于利。 .NET 垃圾收集器实际上非常好,如果您自己强制执行它,您将面临非常高的风险,因为您将对象推送到通常不会存在的第 2 代和第 3 代。
    • @user1492051 同意 Liath - 不要强制垃圾收集开始。如果您的应用程序不需要在堆上分配新内存,那么您的死对象就不是问题。如果需要空闲内存,GC 会自动收集所有垃圾
    【解决方案2】:

    GC 将收集不再引用的项目。不过,何时执行取决于它自己。

    所以:是的,将对 ObjectD 的引用设置为 null 将使 GC 能够收集它。不,它(很可能)不会立即发生。

    【讨论】:

      【解决方案3】:

      您可以将对象设置为 null,然后使用 Collect 方法 Gc.Collect()。它执行所有代的阻塞垃圾收集。所有对象,无论它们在内存中存在多长时间,都将被考虑收集。

      【讨论】:

      • 我会警告不要自己强制垃圾收集。第二代和第三代对象可能需要更多的时间和精力来回收,通过自己强制进行额外的收集(虽然您可能会释放一些资源),您更有可能将项目强制放入这些后代并实际损坏您的性能。
      【解决方案4】:

      如果将D设置为null,则可以在调用GC时将其从内存中删除。但在对象中包含空字段并不是一个好的解决方案。如果它需要临时的,也许它应该是一个局部变量!?

      【讨论】:

        【解决方案5】:
        if an object sets for so long unused in some scope what does .NET do about it?
        

        为了回收内存,垃圾收集器收集并销毁不再可用的对象,即当没有对它的引用时,所有引用都设置为 null,或者对它的所有引用都来自其他可以被集。收集的过程涉及将可用对象移动到内存中并回收不再使用的对象使用的内存。在集合中存活的对象会自动提升到下一代

        【讨论】:

          【解决方案6】:
          1. 将内存设置为 NULL 不会立即释放内存。内存将被标记为垃圾回收。 .Net GC 方案有些高效。如果您担心,可以强制进行一次 GC 循环:See this stack overflow article on the yin/yang of this.

          2. 如果它设置为未使用,.Net 将不会做任何事情。也就是说,如果您不专门“取消”引用,.Net 没有理由期望在某些时候(立即)不需要该对象。如果您需要它并且.Net“暂时将其从内存中删除”,它将需要以某种方式重新创建它,使用有关您的班级状态的信息......恢复信息的明显选择是班级本身。所以删除它并不是一个真正的选择。

          通过较慢但较大的内存访问的各个阶段卸载它通常是现代计算机中使用的策略:(1) 将内存存储在本地片上内存缓存中,用于最近使用的数据/程序。 (2) 将内存存储在片外存储芯片中。 (3) 将内存存储在虚拟化媒体(例如硬盘)中。

          归根结底,您可能最清楚何时取消引用,而框架最清楚何时/何处为您的对象存储内存。在游戏编程等例外情况下,GC 机制可能会导致打嗝。但总的来说,只要你做得好,系统就会做得很好。

          这有帮助吗?

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-21
            • 1970-01-01
            • 1970-01-01
            • 2018-12-30
            • 1970-01-01
            • 1970-01-01
            • 2010-12-13
            • 2012-05-04
            相关资源
            最近更新 更多