.NET Core - 垃圾回收

在本章中,我们将介绍垃圾回收的概念,这是 .NET 托管代码平台最重要的功能之一。 垃圾回收器 (GC) 管理内存的分配和释放。 垃圾回收器充当自动内存管理器。

  • 您不需要知道如何分配和释放内存或管理使用该内存的对象的生命周期

  • 每当您使用"new"关键字声明一个对象或装箱一个值类型时,就会进行一次分配。 分配通常非常快

  • 当没有足够的内存来分配一个对象时,GC 必须收集并处理垃圾内存,以便为新的分配提供可用内存。

  • 此过程称为垃圾回收


垃圾回收的优点

垃圾回收提供以下好处 −

  • 您无需在开发应用程序时手动释放内存。

  • 它还能在托管堆上有效地分配对象。

  • 当不再使用对象时,它将通过清除内存来回收这些对象,并保留内存以供将来分配。

  • 托管对象会自动获取干净的内容作为开始,因此它们的构造函数不必初始化每个数据字段。

  • 它还通过确保一个对象无法使用另一个对象的内容来提供内存安全。


垃圾回收条件

当下列条件之一为真时,垃圾回收发生。

  • 系统物理内存不足。

  • 托管堆上分配的对象使用的内存超过可接受的阈值。 该阈值会随着流程的运行而不断调整。

  • 调用GC.Collect 方法,几乎在所有情况下,您都不必调用此方法,因为垃圾回收器会连续运行。 此方法主要用于特殊情况和测试。


世代

.NET 垃圾回收器有 3 代,每一代都有自己的堆,用于存储分配的对象。 有一个基本原则,即大多数对象要么是短命的,要么是长命的。

第一代(0)

  • 在第 0 代中,首先分配对象。

  • 在这一代中,对象通常活不过第一代,因为在下一次垃圾回收发生时它们已不再使用(超出范围)。

  • 第 0 代可以快速收集,因为它关联的堆很小。

第二代(1)

  • 在第 1 代中,对象有第二次机会空间。

  • 生命周期短暂但在第 0 代收集中幸存下来的对象(通常基于巧合的时间)进入第 1 代。

  • 第 1 代收集也很快,因为它的关联堆也很小。

  • 前两个堆仍然很小,因为对象要么被收集要么提升到下一代堆。

第三代(2)

  • 在第 2 代中,所有长对象都是存活的,它的堆可以增长到非常大。

  • 这一代中的对象可以存活很长时间,没有下一代堆进一步提升对象。

  • 垃圾回收器有一个用于大对象的额外堆,称为大对象堆 (LOH)。

  • 为 85,000 字节或更大的对象保留。

  • 大对象不分配到分代堆中,而是直接分配到LOH中

  • 第 2 代和 LOH 收集对于运行了很长时间或对大量数据进行操作的程序来说可能需要很长时间。

  • 众所周知,大型服务器程序的堆大小为 10 GB。

  • GC 采用多种技术来减少它阻止程序执行的时间。

  • 主要方法是以不干扰程序执行的方式在后台线程上执行尽可能多的垃圾回收工作。

  • GC 还为开发人员提供了一些影响其行为的方法,这对于提高性能非常有用。