.NET Core 垃圾回收
本章中,我们将介绍垃圾回收的概念,这是.NET托管代码平台最重要的特征之一。垃圾回收( GC )管理内存的分配和释放,垃圾回收充当自动内存管理器。
你不需要知道如何分配和释放内存或者管理使用内存的对象的生命周期
每当你用“new”关键字声明一个对象或者值类型被装箱时,就会进行分配。分配通常非常快
当内存不足以分配对象时,GC必须收集并处置垃圾内存,以使内存可用于新的分配。
这个过程被称为垃圾回收。
垃圾回收的优点
垃圾回收提供以下好处:
开发应用程序时,不需要手动释放内存。
它还有效地分配托管堆上的对象。
当对象不再使用时,它将通过清除它们的内存来回收这些对象,并保持内存可供将来分配。
托管对象会自动获得干净的内容,因此它们的构造函数不必初始化每个数据字段。
它还通过确保一个对象不能使用另一个对象的内容来提供内存安全性。
垃圾回收的条件
垃圾回收当下列条件之一为true时发生。
系统物理内存不足。
托管堆上分配的对象使用的内存超过了可接受的阈值。随着进程的运行,此阈值会不断调整。
GC.Collect方法被调用,在几乎所有情况下,你都不必调用这个方法,因为垃圾回收连续运行。这种方法主要用于特殊情况和测试。
阶段过程
.NET垃圾回收有3代,每一代都有自己的堆,用于存储分配的对象。有一个基本原则,大多数物体要么是短期的,要么是长期的。
第一代(0)
在第0代中,首先分配对象。
在这一代中,对象通常不会超过第一代,因为到下一代时它们已经不再使用(超出范围)垃圾回收发生。
第0代收集速度很快,因为它关联的堆很小。
第二代(1)
在第1代中,对象有第二次机会空间。
短暂但在第0代收藏中幸存下来的对象(通常基于巧合的时间)会被转移到第1代。
第1代集合也很快,因为它关联的堆也很小。
前两个堆仍然很小,因为对象要么被收集,要么被提升到下一代堆。
第三代(2)
在第二代中,所有长对象都存在,其堆可能会变得非常大。
这一代的对象可以存活很长时间,并且没有下一代堆来进一步提升对象。
这垃圾回收有一个额外的大对象堆,称为大对象堆( LOH )。
它是为85,000字节或更大的对象保留的。
大型对象不会分配给世代堆,而是直接分配给LOH
对于已经运行了很长时间或在大量数据上运行的程序来说,第二代和LOH集合可能需要很长时间。
众所周知,大型服务器程序在几十GBs中有堆。
GC采用了多种技术来减少阻止程序执行的时间。
主要的方法是做同样多的事情垃圾回收以不干扰程序执行的方式尽可能在后台线程上工作。
GC还公开了一些开发人员影响其行为的方法,这对提高性能非常有用。