.NET 内存管理概念
为了有效使用 dotMemory,您需要对 .NET 如何管理内存有一个大致的了解。 本节总结了 .NET 内存概念。 有关更多信息,您可以参考 Microsoft Learn 或网络上的其他资料。
内存分配
垃圾回收器(GC)是 .NET 框架的一部分,负责为您的 .NET 应用程序分配和释放内存。
当一个新进程启动时,运行时会为该进程保留一个称为托管堆的地址空间区域。
对象在堆中一个接一个地连续分配。
内存分配是一个非常快速的过程,因为它只是将一个值添加到指针。
除了托管堆之外,应用程序总是会消耗一定量的所谓非托管*内存,这些内存不由 GC 管理。
内存释放
释放内存的过程称为垃圾回收。
当 GC 执行回收时,它只释放不再被应用程序使用的对象(例如,方法中的局部变量只能在方法执行期间访问,之后该变量不再需要)。
为了确定对象是否被使用,GC 会检查应用程序的根——对应用程序全局的强引用。 通常,这些是全局和静态对象指针、局部变量以及 CPU 寄存器。 在 分析 GC Roots 中了解更多可能的 GC 根。
对于每个活动根,GC 会构建一个包含从这些根可达的所有对象的图。
如果一个对象不可达,GC 会认为它不再被使用,并将其从堆中移除(释放该对象占用的内存)。
在对象被移除后,GC 会压缩内存中可达的对象。

代系
为了更高效地释放内存,托管堆被分为称为代的段:0、1 和 2。
当对象刚被创建时,它们会被放置在第 0 代(Gen 0)。
当第 0 代已满时(堆和代的大小由 GC 定义),GC 会执行一次垃圾回收。 在回收过程中,GC 会从堆中移除所有不可达的对象。 所有可达的对象会被提升到第 1 代(Gen 1)。
第 0 代的回收是一个相当快速的操作。
当第 1 代已满时,会执行第 1 代的垃圾回收。 所有在回收中存活的对象会被提升到第 2 代(Gen 2)。 第 0 代的回收也会在此时进行。
当第 2 代已满时,GC 会执行完整垃圾回收。 首先执行第 2 代的回收,之后依次执行第 1 代和第 0 代的回收。 如果仍然没有足够的内存进行新的分配,GC 会引发
OutOfMemory异常。在完整垃圾回收期间,GC 必须遍历堆中的所有对象,因此此过程可能对系统资源产生较大影响。

大对象堆
出于性能原因,大对象(大于 85 KB)存储在托管堆的一个单独段中,称为大对象堆(LOH)。
LOH 中存活的对象不会被压缩 *。 这意味着 LOH 会随着时间的推移而变得碎片化。
