自动内存管理是公共语言运行时在托管执行过程过程中提供的服务之一。 公共语言运行时的垃圾回收器为应用程序管理内存的分配和释放。对开发人员而言,这意味着在开发托管应用程序时不必编写执行内存管理任务的代码。 自动内存管理可解决常见问题,例如,忘记释放对象并导致内存泄漏,或尝试访问已释放对象的内存。 本节描述垃圾回收器如何分配和释放内存。

  分配内存

  初始化新进程时,运行时会为进程保留一个连续的地址空间区域。 这个保留的地址空间被称为托管堆。 托管堆维护着一个指针,用它指向将在堆中分配的下一个对象的地址。初,该指针设置为指向托管堆的基址。 托管堆上部署了所有引用类型。 应用程序创建第一个引用类型时,将为托管堆的基址中的类型分配内存。应用程序创建下一个对象时,垃圾回收器在紧接第一个对象后面的地址空间内为它分配内存。 只要地址空间可用,垃圾回收器会继续以这种方式为新对象分配空间。

  从托管堆中分配内存要比非托管内存分配速度快。由于运行时通过为指针添加值来为对象分配内存,所以这几乎和从堆栈中分配内存一样快。另外,由于连续分配的新对象在托管堆中是连续存储,所以应用程序可以快速访问这些对象。

  释放内存

  垃圾回收器的优化引擎根据所执行的分配决定执行回收的佳时间。垃圾回收器在执行回收时,会释放应用程序不再使用的对象的内存。 它通过检查应用程序的根来确定不再使用的对象。 每个应用程序都有一组根。每个根或者引用托管堆中的对象,或者设置为空。应用程序的根包含全局对象指针、静态对象指针、线程堆栈中的局部变量和引用对象参数以及 CPU 寄存器。垃圾回收器可以访问由实时 (JIT) 编译器和运行时维护的活动根的列表。垃圾回收器对照此列表检查应用程序的根,并在此过程中创建一个图表,在其中包含所有可从这些根中访问的对象。

  不在该图表中的对象将无法从应用程序的根中访问。垃圾回收器会考虑无法访问的对象垃圾,并释放为它们分配的内存。 在回收中,垃圾回收器检查托管堆,查找无法访问对象所占据的地址空间块。发现无法访问的对象时,它使用内存复制功能来压缩内存中可以访问的对象,释放分配给不可访问对象的地址空间块。在压缩了可访问对象的内存后,垃圾回收器会做出必要的指针更正,以便应用程序的根指向新地址中的对象。 它还将托管堆指针定位至后一个可访问对象之后。请注意,只有在回收发现大量的无法访问的对象时,才会压缩内存。 如果托管堆中的所有对象均未被回收,则不需要压缩内存。

  为了改进性能,运行时为单独堆中的大型对象分配内存。 垃圾回收器会自动释放大型对象的内存。但是,为了避免移动内存中的大型对象,不会压缩此内存。