垃圾回收的基本知识Fundamentals of garbage collection

在公共语言运行时 (CLR) 中,垃圾回收器 (GC) 用作自动内存管理器。In the common language runtime (CLR), the garbage collector (GC) serves as an automatic memory manager. 它提供如下优点:It provides the following benefits:

  • 使你可以在开发应用程序时不必手动释放内存。Enables you to develop your application without having to manually free memory.

  • 有效分配托管堆上的对象。Allocates objects on the managed heap efficiently.

  • 回收不再使用的对象,清除它们的内存,并保留内存以用于将来分配。Reclaims objects that are no longer being used, clears their memory, and keeps the memory available for future allocations. 托管对象会自动获取干净的内容来开始,因此,它们的构造函数不必对每个数据字段进行初始化。Managed objects automatically get clean content to start with, so their constructors do not have to initialize every data field.

  • 通过确保对象不能使用另一个对象的内容来提供内存安全。Provides memory safety by making sure that an object cannot use the content of another object.

本文章介绍垃圾回收的核心概念。This article describes the core concepts of garbage collection.

内存基础知识Fundamentals of memory

下面的列表总结了重要的 CLR 内存概念。The following list summarizes important CLR memory concepts.

  • 每个进程都有其自己单独的虚拟地址空间。Each process has its own, separate virtual address space. 同一台计算机上的所有进程共享相同的物理内存和页文件(如果有)。All processes on the same computer share the same physical memory and the page file, if there is one.

  • 默认情况下,32 位计算机上的每个进程都具有 2 GB 的用户模式虚拟地址空间。By default, on 32-bit computers, each process has a 2-GB user-mode virtual address space.

  • 作为一名应用程序开发人员,你只能使用虚拟地址空间,请勿直接操控物理内存。As an application developer, you work only with virtual address space and never manipulate physical memory directly. 垃圾回收器为你分配和释放托管堆上的虚拟内存。The garbage collector allocates and frees virtual memory for you on the managed heap.

    如果你编写的是本机代码,请使用 Windows 函数处理虚拟地址空间。If you are writing native code, you use Windows functions to work with the virtual address space. 这些函数为你分配和释放本机堆上的虚拟内存。These functions allocate and free virtual memory for you on native heaps.

  • 虚拟内存有三种状态:Virtual memory can be in three states:

    • 可用。Free. 该内存块没有引用关系,可用于分配。The block of memory has no references to it and is available for allocation.

    • 保留。Reserved. 内存块可供你使用,并且不能用于任何其他分配请求。The block of memory is available for your use and cannot be used for any other allocation request. 但是,在该内存块提交之前,你无法将数据存储到其中。However, you cannot store data to this memory block until it is committed.

    • 提交。Committed. 内存块已指派给物理存储。The block of memory is assigned to physical storage.

  • 可能会存在虚拟地址空间碎片。Virtual address space can get fragmented. 就是说地址空间中存在一些被称为孔的可用块。This means that there are free blocks, also known as holes, in the address space. 当请求虚拟内存分配时,虚拟内存管理器必须找到满足该分配请求的足够大的单个可用块。When a virtual memory allocation is requested, the virtual memory manager has to find a single free block that is large enough to satisfy that allocation request. 即使有 2GB 可用空间,2GB 分配请求也会失败,除非所有这些可用空间都位于一个地址块中。Even if you have 2 GB of free space, the allocation that requires 2 GB will be unsuccessful unless all of that free space is in a single address block.

  • 如果没有足够的可供保留的虚拟地址空间或可供提交的物理空间,则可能会用尽内存。You can run out of memory if there isn't enough virtual address space to reserve or physical space to commit.

    即使在物理内存压力(即物理内存的需求)较低的情况下也会使用页文件。The page file is used even if physical memory pressure (that is, demand for physical memory) is low. 首次出现物理内存压力较高的情况时,操作系统必须在物理内存中腾出空间来存储数据,并将物理内存中的部分数据备份到页文件中。The first time physical memory pressure is high, the operating system must make room in physical memory to store data, and it backs up some of the data that is in physical memory to the page file. 该数据只会在需要时进行分页,所以在物理内存压力较低的情况下也可能会进行分页。That data is not paged until it's needed, so it's possible to encounter paging in situations where the physical memory pressure is low.

垃圾回收的条件Conditions for a garbage collection

当满足以下条件之一时将发生垃圾回收:Garbage collection occurs when one of the following conditions is true:

  • 系统具有低的物理内存。The system has low physical memory. 这是通过 OS 的内存不足通知或主机指示的内存不足检测出来。This is detected by either the low memory notification from the OS or low memory as indicated by the host.

  • 由托管堆上已分配的对象使用的内存超出了可接受的阈值。The memory that is used by allocated objects on the managed heap surpasses an acceptable threshold. 随着进程的运行,此阈值会不断地进行调整。This threshold is continuously adjusted as the process runs.

  • 调用 GC.Collect 方法。The GC.Collect method is called. 几乎在所有情况下,你都不必调用此方法,因为垃圾回收器会持续运行。In almost all cases, you do not have to call this method, because the garbage collector runs continuously. 此方法主要用于特殊情况和测试。This method is primarily used for unique situations and testing.

托管堆The managed heap

在垃圾回收器由 CLR 初始化之后,它会分配一段内存用于存储和管理对象。After the garbage collector is initialized by the CLR, it allocates a segment of memory to store and manage objects. 此内存称为托管堆(与操作系统中的本机堆相对)。This memory is called the managed heap, as opposed to a native heap in the operating system.

每个托管进程都有一个托管堆。There is a managed heap for each managed process. 进程中的所有线程都在同一堆上为对象分配内存。All threads in the process allocate memory for objects on the same heap.

若要保留内存,垃圾回收器会调用 Windows VirtualAlloc 函数,并且每次为托管应用保留一个内存段。To reserve memory, the garbage collector calls the Windows VirtualAlloc function and reserves one segment of memory at a time for managed applications. 垃圾回收器还会根据需要保留内存段,并调用 Windows VirtualFree 函数,将内存段释放回操作系统(在清除所有对象的内存段后)。The garbage collector also reserves segments, as needed, and releases segments back to the operating system (after clearing them of any objects) by calling the Windows VirtualFree function.

重要

垃圾回收器分配的段大小特定于实现,并且随时可能更改(包括定期更新)。The size of segments allocated by the garbage collector is implementation-specific and is subject to change at any time, including in periodic updates. 应用程序不应假设特定段的大小或依赖于此大小,也不应尝试配置段分配可用的内存量。Your app should never make assumptions about or depend on a particular segment size, nor should it attempt to configure the amount of memory available for segment allocations.

堆上分配的对象越少,垃圾回收器必须执行的工作就越少。The fewer objects allocated on the heap, the less work the garbage collector has to do. 分配对象时,请勿使用超出你需求的舍入值,例如在仅需要 15 个字节的情况下分配了 32 个字节的数组。When you allocate objects, do not use rounded-up values that exceed your needs, such as allocating an array of 32 bytes when you need only 15 bytes.

当触发垃圾回收时,垃圾回收器将回收由死对象占用的内存。When a garbage collection is triggered, the garbage collector reclaims the memory that is occupied by dead objects. 回收进程会对活动对象进行压缩,以便将它们一起移动,并移除死空间,从而使堆更小一些。The reclaiming process compacts live objects so that they are moved together, and the dead space is removed, thereby making the heap smaller. 这将确保一起分配的对象全都位于托管堆上,从而保留它们的局部性。This ensures that objects that are allocated together stay together on the managed heap, to preserve their locality.

垃圾回收的侵入性(频率和持续时间)是由分配的数量和托管堆上保留的内存数量决定的。The intrusiveness (frequency and duration) of garbage collections is the result of the volume of allocations and the amount of survived memory on the managed heap.

此堆可视为两个堆的累计:大对象堆和小对象堆。The heap can be considered as the accumulation of two heaps: the large object heap and the small object heap.

大对象堆包含大小为 85,000 个字节和更多字节的大型对象。The large object heap contains very large objects that are 85,000 bytes and larger. 大对象堆上的对象通常是数组。The objects on the large object heap are usually arrays. 非常大的实例对象是很少见的。It is rare for an instance object to be extremely large.

提示

可以配置阈值大小,以使对象能够进入大型对象堆。You can configure the threshold size for objects to go on the large object heap.

代数Generations

堆按代进行组织,因此它可以处理长生存期的对象和短生存期的对象。The heap is organized into generations so it can handle long-lived and short-lived objects. 垃圾回收主要在回收通常只占用一小部分堆的短生存期对象时发生。Garbage collection primarily occurs with the reclamation of short-lived objects that typically occupy only a small part of the heap. 堆上的对象有三代:There are three generations of objects on the heap:

  • 第 0 代Generation 0. 这是最年轻的代,其中包含短生存期对象。This is the youngest generation and contains short-lived objects. 短生存期对象的一个示例是临时变量。An example of a short-lived object is a temporary variable. 垃圾回收最常发生在此代中。Garbage collection occurs most frequently in this generation.

    新分配的对象构成新一代对象,并隐式地成为第 0 代集合。Newly allocated objects form a new generation of objects and are implicitly generation 0 collections. 但是,如果它们是大型对象,它们将延续到第 2 代集合中的大型对象堆。However, if they are large objects, they go on the large object heap in a generation 2 collection.

    大多数对象通过第 0 代中的垃圾回收进行回收,不会保留到下一代。Most objects are reclaimed for garbage collection in generation 0 and do not survive to the next generation.

  • 第 1 代Generation 1. 这一代包含短生存期对象并用作短生存期对象和长生存期对象之间的缓冲区。This generation contains short-lived objects and serves as a buffer between short-lived objects and long-lived objects.

  • 第 2 代Generation 2. 这一代包含长生存期对象。This generation contains long-lived objects. 长生存期对象的一个示例是服务器应用程序中的一个包含在进程期间处于活动状态的静态数据的对象。An example of a long-lived object is an object in a server application that contains static data that's live for the duration of the process.

当条件得到满足时,垃圾回收将在特定代上发生。Garbage collections occur on specific generations as conditions warrant. 回收某个代意味着回收此代中的对象及其所有更年轻的代。Collecting a generation means collecting objects in that generation and all its younger generations. 第 2 代垃圾回收也称为完整垃圾回收,因为它回收所有代上的所有对象(即,托管堆中的所有对象)。A generation 2 garbage collection is also known as a full garbage collection, because it reclaims all objects in all generations (that is, all objects in the managed heap).

幸存和提升Survival and promotions

垃圾回收中未回收的对象也称为幸存者,并会被提升到下一代。Objects that are not reclaimed in a garbage collection are known as survivors and are promoted to the next generation. 在第 0 代垃圾回收中幸存的对象将被提升到第 1 代;在第 1 代垃圾回收中幸存的对象将被提升到第 2 代;而在第 2 代垃圾回收中幸存的对象将仍为第 2 代。Objects that survive a generation 0 garbage collection are promoted to generation 1; objects that survive a generation 1 garbage collection are promoted to generation 2; and objects that survive a generation 2 garbage collection remain in generation 2.

当垃圾回收器检测到某个代中的幸存率很高时,它会增加该代的分配阈值。When the garbage collector detects that the survival rate is high in a generation, it increases the threshold of allocations for that generation. 下次回收将回收非常大的内存。The next collection gets a substantial size of reclaimed memory. CLR 持续在以下两个优先级之间进行平衡:不允许通过延迟垃圾回收,让应用程序的工作集获取太大内存,以及不允许垃圾回收过于频繁地运行。The CLR continually balances two priorities: not letting an application's working set get too large by delaying garbage collection and not letting the garbage collection run too frequently.

暂时代和暂时段Ephemeral generations and segments

因为第 0 代和第 1 代中的对象的生存期较短,因此,这些代被称为暂时代。Because objects in generations 0 and 1 are short-lived, these generations are known as the ephemeral generations.

暂时代必须在称为暂时段的内存段中进行分配。Ephemeral generations must be allocated in the memory segment that is known as the ephemeral segment. 垃圾回收器获取的每个新段将成为新的暂时段,并包含在第 0 代垃圾回收中幸存的对象。Each new segment acquired by the garbage collector becomes the new ephemeral segment and contains the objects that survived a generation 0 garbage collection. 旧的暂时段将成为新的第 2 代段。The old ephemeral segment becomes the new generation 2 segment.

根据系统为 32 位还是 64 位以及它正在哪种类型的垃圾回收器上运行,暂时段的大小发生相应变化。The size of the ephemeral segment varies depending on whether a system is 32-bit or 64-bit, and on the type of garbage collector it is running. 下表列出了默认值。Default values are shown in the following table.

32 位32-bit 64 位64-bit
工作站 GCWorkstation GC 16 MB16 MB 256 MB256 MB
服务器 GCServer GC 64 MB64 MB 4 GB4 GB
服务器 GC(具有 4 个以上的逻辑 CPU)Server GC with > 4 logical CPUs 32 MB32 MB 2 GB2 GB
服务器 GC(具有 8 个以上的逻辑 CPU)Server GC with > 8 logical CPUs 16 MB16 MB 1 GB1 GB

暂时段可以包含第 2 代对象。The ephemeral segment can include generation 2 objects. 第 2 代对象可使用多个段(在内存允许的情况下进程所需的任意数量)。Generation 2 objects can use multiple segments (as many as your process requires and memory allows for).

从暂时垃圾回收中释放的内存量限制为暂时段的大小。The amount of freed memory from an ephemeral garbage collection is limited to the size of the ephemeral segment. 释放的内存量与死对象占用的空间成比例。The amount of memory that is freed is proportional to the space that was occupied by the dead objects.

垃圾回收过程中发生的情况What happens during a garbage collection

垃圾回收分为以下几个阶段:A garbage collection has the following phases:

  • 标记阶段,找到并创建所有活动对象的列表。A marking phase that finds and creates a list of all live objects.

  • 重定位阶段,用于更新对将要压缩的对象的引用。A relocating phase that updates the references to the objects that will be compacted.

  • 压缩阶段,用于回收由死对象占用的空间,并压缩幸存的对象。A compacting phase that reclaims the space occupied by the dead objects and compacts the surviving objects. 压缩阶段将垃圾回收中幸存下来的对象移至段中时间较早的一端。The compacting phase moves objects that have survived a garbage collection toward the older end of the segment.

    因为第 2 代回收可以占用多个段,所以可以将已提升到第 2 代中的对象移动到时间较早的段中。Because generation 2 collections can occupy multiple segments, objects that are promoted into generation 2 can be moved into an older segment. 可以将第 1 代幸存者和第 2 代幸存者都移动到不同的段,因为它们已被提升到第 2 代。Both generation 1 and generation 2 survivors can be moved to a different segment, because they are promoted to generation 2.

    通常,由于复制大型对象会造成性能代偿,因此不会压缩大型对象堆 (LOH)。Ordinarily, the large object heap (LOH) is not compacted, because copying large objects imposes a performance penalty. 但是,在 .NET Core 和 .NET Framework 4.5.1 及更高版本中,可以根据需要使用 GCSettings.LargeObjectHeapCompactionMode 属性按需压缩大型对象堆。However, in .NET Core and in .NET Framework 4.5.1 and later, you can use the GCSettings.LargeObjectHeapCompactionMode property to compact the large object heap on demand. 此外,当通过指定以下任一项设置硬限制时,将自动压缩 LOH:In addition, the LOH is automatically compacted when a hard limit is set by specifying either:

垃圾回收器使用以下信息来确定对象是否为活动对象:The garbage collector uses the following information to determine whether objects are live:

  • 堆栈根Stack roots. 由实时 (JIT) 编译器和堆栈查看器提供的堆栈变量。Stack variables provided by the just-in-time (JIT) compiler and stack walker. JIT 优化可以延长或缩短报告给垃圾回收器的堆栈变量内的代码的区域。JIT optimizations can lengthen or shorten regions of code within which stack variables are reported to the garbage collector.

  • 垃圾回收句柄Garbage collection handles. 指向托管对象且可由用户代码或公共语言运行时分配的句柄。Handles that point to managed objects and that can be allocated by user code or by the common language runtime.

  • 静态数据Static data. 应用程序域中可能引用其他对象的静态对象。Static objects in application domains that could be referencing other objects. 每个应用程序域都会跟踪其静态对象。Each application domain keeps track of its static objects.

在垃圾回收启动之前,除了触发垃圾回收的线程以外的所有托管线程均会挂起。Before a garbage collection starts, all managed threads are suspended except for the thread that triggered the garbage collection.

下图演示了触发垃圾回收并导致其他线程挂起的线程。The following illustration shows a thread that triggers a garbage collection and causes the other threads to be suspended.

线程触发垃圾回收时

操作非托管资源Manipulate unmanaged resources

如果托管对象使用非托管对象的本机文件句柄来引用非托管对象,则必须显式释放非托管对象,因为垃圾回收器仅跟踪托管堆上的内存。If managed objects reference unmanaged objects by using their native file handles, you have to explicitly free the unmanaged objects, because the garbage collector only tracks memory on the managed heap.

托管对象的用户可能不会释放由该对象使用的本机资源。Users of the managed object may not dispose the native resources used by the object. 为了执行清理,可以使托管对象成为可终结的。To perform the cleanup, you can make the managed object finalizable. 终结由不再使用对象时执行的清理操作组成。Finalization consists of cleanup actions that execute when the object is no longer in use. 当托管对象不活动时,它将执行在其终结器方法中指定的清理操作。When the managed object dies, it performs cleanup actions that are specified in its finalizer method.

当发现某个可终结对象处于不活动状态时,则会将其终结器放入队列中,以便执行其清理操作,但要将该对象自身提升到下一代。When a finalizable object is discovered to be dead, its finalizer is put in a queue so that its cleanup actions are executed, but the object itself is promoted to the next generation. 因此,你必须等待该代上发生下一次垃圾回收(并不一定是下一次垃圾回收),以确定对象是否已收回。Therefore, you have to wait until the next garbage collection that occurs on that generation (which is not necessarily the next garbage collection) to determine whether the object has been reclaimed.

有关终结版的详细信息,请参见 Object.Finalize()For more information about finalization, see Object.Finalize().

工作站和服务器垃圾回收Workstation and server garbage collection

垃圾回收器可自行优化并且适用于多种方案。The garbage collector is self-tuning and can work in a wide variety of scenarios. 你可使用配置文件设置来基于工作负荷的特征设置垃圾回收的类型。You can use a configuration file setting to set the type of garbage collection based on the characteristics of the workload. CLR 提供了以下类型的垃圾回收:The CLR provides the following types of garbage collection:

  • 工作站垃圾回收 (GC) 是为客户端应用为设计的。Workstation garbage collection (GC) is designed for client apps. 它是独立应用的默认 GC 风格。It is the default GC flavor for standalone apps. 对于托管应用(例如由 ASP.NET 托管的应用),由主机确定默认 GC 风格。For hosted apps, for example, those hosted by ASP.NET, the host determines the default GC flavor.

    工作站垃圾回收既可以是并发的,也可以是非并发的。Workstation garbage collection can be concurrent or non-concurrent. 并发垃圾回收使托管线程能够在垃圾回收期间继续操作。Concurrent garbage collection enables managed threads to continue operations during a garbage collection. 后台垃圾回收替换 .NET Framework 4 及更高版本中的并行垃圾回收Background garbage collection replaces concurrent garbage collection in .NET Framework 4 and later versions.

  • 服务器垃圾回收,用于需要高吞吐量和可伸缩性的服务器应用程序。Server garbage collection, which is intended for server applications that need high throughput and scalability.

    • 在 .NET Core 中,服务器垃圾回收既可以是非并发也可以是后台执行。In .NET Core, server garbage collection can be non-concurrent or background.

    • 在 .NET Framework 4.5 及更高版本中,服务器垃圾回收可以非并行运行,还可在后台运行(后台垃圾回收可取代并行垃圾回收)。In .NET Framework 4.5 and later versions, server garbage collection can be non-concurrent or background (background garbage collection replaces concurrent garbage collection). 在 .NET Framework 4 和以前的版本中,服务器垃圾回收非并行运行。In .NET Framework 4 and previous versions, server garbage collection is non-concurrent.

下图演示了服务器上执行垃圾回收的专用线程:The following illustration shows the dedicated threads that perform the garbage collection on a server:

服务器垃圾回收线程

比较工作站和服务器垃圾回收Compare workstation and server garbage collection

以下是工作站垃圾回收的线程处理和性能注意事项:The following are threading and performance considerations for workstation garbage collection:

  • 回收发生在触发垃圾回收的用户线程上,并保留相同优先级。The collection occurs on the user thread that triggered the garbage collection and remains at the same priority. 因为用户线程通常以普通优先级运行,所以垃圾回收器(在普通优先级线程上运行)必须与其他线程竞争 CPU 时间。Because user threads typically run at normal priority, the garbage collector (which runs on a normal priority thread) must compete with other threads for CPU time. (运行本机代码的线程不会由于服务器或工作站垃圾回收而挂起。)(Threads that run native code are not suspended on either server or workstation garbage collection.)

  • 工作站垃圾回收始终用于只有一个处理器的计算机,无论配置设置如何。Workstation garbage collection is always used on a computer that has only one processor, regardless of the configuration setting.

以下是服务器垃圾回收的线程处理和性能注意事项:The following are threading and performance considerations for server garbage collection:

  • 回收发生在以 THREAD_PRIORITY_HIGHEST 优先级运行的多个专用线程上。The collection occurs on multiple dedicated threads that are running at THREAD_PRIORITY_HIGHEST priority level.

  • 为每个 CPU 提供一个用于执行垃圾回收的一个堆和专用线程,并将同时回收这些堆。A heap and a dedicated thread to perform garbage collection are provided for each CPU, and the heaps are collected at the same time. 每个堆都包含一个小对象堆和一个大对象堆,并且所有的堆都可由用户代码访问。Each heap contains a small object heap and a large object heap, and all heaps can be accessed by user code. 不同堆上的对象可以相互引用。Objects on different heaps can refer to each other.

  • 因为多个垃圾回收线程一起工作,所以对于相同大小的堆,服务器垃圾回收比工作站垃圾回收更快一些。Because multiple garbage collection threads work together, server garbage collection is faster than workstation garbage collection on the same size heap.

  • 服务器垃圾回收通常具有更大的段。Server garbage collection often has larger size segments. 但是,这是通常情况:段大小特定于实现且可能更改。However, this is only a generalization: segment size is implementation-specific and is subject to change. 调整应用程序时,不要假设垃圾回收器分配的段大小。Don't make assumptions about the size of segments allocated by the garbage collector when tuning your app.

  • 服务器垃圾回收会占用大量资源。Server garbage collection can be resource-intensive. 例如,假设在一台有 4 个处理器的计算机上,运行着 12 个使用服务器 GC 的进程。For example, imagine that there are 12 processes that use server GC running on a computer that has 4 processors. 如果所有进程碰巧同时回收垃圾,它们会相互干扰,因为将在同一个处理器上调度 12 个线程。If all the processes happen to collect garbage at the same time, they would interfere with each other, as there would be 12 threads scheduled on the same processor. 如果进程处于活动状态,则最好不要让它们都使用服务器 GC。If the processes are active, it's not a good idea to have them all use server GC.

如果运行应用程序的数百个实例,请考虑使用工作站垃圾回收并禁用并发垃圾回收。If you're running hundreds of instances of an application, consider using workstation garbage collection with concurrent garbage collection disabled. 这可以减少上下文切换,从而提高性能。This will result in less context switching, which can improve performance.

后台工作站垃圾回收Background workstation garbage collection

在后台工作站垃圾回收中,在进行第 2 代回收的过程中,将会根据需要收集暂时代(第 0 代和第 1 代)。In background workstation garbage collection, ephemeral generations (0 and 1) are collected as needed while the collection of generation 2 is in progress. 后台工作站垃圾回收是在一个专用线程上执行的并且只适用于第 2 代回收。Background workstation garbage collection is performed on a dedicated thread and applies only to generation 2 collections.

默认启用后台垃圾回收,并且可以在 .NET Framework 应用程序中使用 gcConcurrent 配置设置或 .NET Framework 应用中的 System.GC.Concurrent 来启用或禁用后台垃圾回收。Background garbage collection is enabled by default and can be enabled or disabled with the gcConcurrent configuration setting in .NET Framework apps or the System.GC.Concurrent setting in .NET Core apps.

备注

后台垃圾回收替换在 .NET Framework 4 及更高版本中可用的并行垃圾回收Background garbage collection replaces concurrent garbage collection and is available in .NET Framework 4 and later versions. 在 .NET Framework 4 中,仅支持工作站垃圾回收。In .NET Framework 4, it's supported only for workstation garbage collection. 从 .NET Framework 4.5 开始,后台垃圾回收可用于工作站和服务器垃圾回收。Starting with .NET Framework 4.5, background garbage collection is available for both workstation and server garbage collection.

后台垃圾回收期间对暂时代的回收称为前台垃圾回收。A collection on ephemeral generations during background garbage collection is known as foreground garbage collection. 发生前台垃圾回收时,所有托管线程都将被挂起。When foreground garbage collections occur, all managed threads are suspended.

当后台垃圾回收正在进行并且你已在第 0 代中分配了足够的对象时,CLR 将执行第 0 代或第 1 代前台垃圾回收。When background garbage collection is in progress and you've allocated enough objects in generation 0, the CLR performs a generation 0 or generation 1 foreground garbage collection. 专用的后台垃圾回收线程将在常见的安全点上进行检查以确定是否存在对前台垃圾回收的请求。The dedicated background garbage collection thread checks at frequent safe points to determine whether there is a request for foreground garbage collection. 如果存在,则后台回收将挂起自身以便前台垃圾回收可以发生。If there is, the background collection suspends itself so that foreground garbage collection can occur. 在前台垃圾回收完成之后,专用的后台垃圾回收线程和用户线程将继续。After the foreground garbage collection is completed, the dedicated background garbage collection thread and user threads resume.

后台垃圾回收可以消除并发垃圾回收所带来的分配限制,因为在后台垃圾回收期间,可发生暂时垃圾回收。Background garbage collection removes allocation restrictions imposed by concurrent garbage collection, because ephemeral garbage collections can occur during background garbage collection. 后台垃圾回收可以删除暂存世代中的死对象。Background garbage collection can remove dead objects in ephemeral generations. 如果需要,它还可以在第 1 代垃圾回收期间扩展堆。It can also expand the heap if needed during a generation 1 garbage collection.

下图显示对工作站上的独立专用线程执行的后台垃圾回收:The following illustration shows background garbage collection performed on a separate dedicated thread on a workstation:

后台工作站垃圾回收

后台服务器垃圾回收Background server garbage collection

从 .NET Framework 4.5 开始,后台服务器垃圾回收是服务器垃圾回收的默认模式。Starting with .NET Framework 4.5, background server garbage collection is the default mode for server garbage collection.

后台服务器垃圾回收与后台工作站垃圾回收(如上一章节所描述)具有类似功能,但有一些不同之处:Background server garbage collection functions similarly to background workstation garbage collection, described in the previous section, but there are a few differences:

  • 后台工作区域垃圾回收使用一个专用的后台垃圾回收线程,而后台服务器垃圾回收使用多个线程。Background workstation garbage collection uses one dedicated background garbage collection thread, whereas background server garbage collection uses multiple threads. 通常一个逻辑处理器有一个专用线程。Typically, there's a dedicated thread for each logical processor.

  • 不同于工作站后台垃圾回收线程,这些线程不会超时。Unlike the workstation background garbage collection thread, these threads do not time out.

下图显示对服务器上的独立专用线程执行的后台垃圾回收:The following illustration shows background garbage collection performed on a separate dedicated thread on a server:

后台服务器垃圾回收

并行垃圾回收Concurrent garbage collection

提示

本部分仅适用于:This section applies to:

  • 用于工作站垃圾回收的 .NET Framework 3.5 及更早版本.NET Framework 3.5 and earlier for workstation garbage collection
  • 用于服务器垃圾回收的 .NET Framework 4 及更早版本.NET Framework 4 and earlier for server garbage collection

在更高的版本中,后台垃圾回收取代了并行垃圾回收。Concurrent garbage is replaced by background garbage collection in later versions.

在工作站或服务器垃圾回收中,你可以启用并发垃圾回收,以便在大多数回收期间,让各线程与执行垃圾回收的专用线程并发运行。In workstation or server garbage collection, you can enable concurrent garbage collection, which enables threads to run concurrently with a dedicated thread that performs the garbage collection for most of the duration of the collection. 此选项只影响第 2 代中的垃圾回收;第 0 代和第 1 代中的垃圾回收始终是非并发的,因为它们完成的速度非常快。This option affects only garbage collections in generation 2; generations 0 and 1 are always non-concurrent because they finish very fast.

并发垃圾回收通过最大程度地减少因回收引起的暂停,使交互应用程序能够更快地响应。Concurrent garbage collection enables interactive applications to be more responsive by minimizing pauses for a collection. 在运行并发垃圾回收线程的大多数时间,托管线程可以继续运行。Managed threads can continue to run most of the time while the concurrent garbage collection thread is running. 这可以使得在发生垃圾回收时的暂停时间更短。This results in shorter pauses while a garbage collection is occurring.

并发垃圾回收在一个专用线程上执行。Concurrent garbage collection is performed on a dedicated thread. 默认情况下,CLR 将运行工作站垃圾回收并启用并发垃圾回收。By default, the CLR runs workstation garbage collection with concurrent garbage collection enabled. 对于单处理器计算机和多处理器计算机都是如此。This is true for single-processor and multi-processor computers.

下图演示了在单独的专用线程上执行的并发垃圾回收。The following illustration shows concurrent garbage collection performed on a separate dedicated thread.

并发垃圾回收线程

请参阅See also