C# 高效垃圾收集

C# 高效垃圾收集,c#,garbage-collection,C#,Garbage Collection,考虑以下对象 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占用大量内存,因此在其角色完成后,我将其设置为null 这是否意味着内存

考虑以下对象

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
占用大量内存,因此在其角色完成后,我将其设置为null

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

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


查看

GC将收集不再引用的项目。然而,当它这样做的时候,这取决于它自己


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

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

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

if an object sets for so long unused in some scope what does .NET do about it?
为了回收内存,垃圾收集器收集并销毁不再可用的对象,即没有对它的引用,所有引用都设置为null,或者对它的所有引用都来自可以收集的其他对象。收集的过程包括将可用对象移动到内存中,并回收不再使用的对象所使用的内存。在集合中幸存的对象将自动升级到下一代

  • 将内存设置为NULL不会立即释放内存。内存将被标记为垃圾回收。Net GC方案在某种程度上是有效的。如果您担心,您可以强制执行GC循环:

  • 如果设置为未使用,.Net将不会执行任何操作。也就是说,如果您没有明确地“取消”引用,.Net没有理由期望该对象在某个点上不需要(立即)。如果您需要它并且.Net“暂时将其从内存中删除”,它将需要以某种方式重新创建它,使用有关类状态的信息…恢复信息的明显选择是类本身。因此,删除它并不是一个真正的选择

  • 现代计算机通常采用的策略是通过不同阶段的较慢但较大的内存访问来卸载内存:(1)将内存存储在本地片上内存缓存中,以存储最近使用的数据/程序。(2) 将内存存储在片外内存芯片中。(3) 将内存存储在虚拟化介质(例如硬盘驱动器)中

    最终,您可能最清楚何时取消引用,框架也最清楚何时/何处存储对象的内存。也有例外,例如游戏编程,GC机制可能导致打嗝。但总的来说,这个系统和你一样好


    这有帮助吗?

    所以垃圾收集器在没有更多引用的情况下进行收集?有没有办法使GC对某个对象不稳定地运行?请注意,垃圾收集器的习惯实际上是不同的,这取决于您选择的构建配置。发布版本更积极地修剪未使用的版本objects@user1492051您可以手动运行垃圾收集,但这是一个非常昂贵的操作,它会影响应用程序中的所有垃圾对象,不仅仅是这个one@user1492051请看我对另一个问题的评论——强制收藏确实是可能的,但这往往弊大于利。NET垃圾回收器实际上相当不错,如果您自己强制执行,您将面临非常高的风险,因为您将对象推到通常不存在的第二代和第三代中。@user1492051同意Liath-不要强制启动垃圾回收。如果您的应用程序不需要在堆上分配新内存,那么您的死对象就不是问题。如果需要空闲内存,GC将自动收集所有垃圾。我警告不要自己强制垃圾收集。第二代和第三代对象可能需要花费更多的时间和精力来回收,通过强制自己进行额外的收集(虽然您可能会释放一些资源),很可能会强制将项目放入这些后续代中,并实际损害您的性能。