diff --git a/docs/core/run-time-config/garbage-collector.md b/docs/core/run-time-config/garbage-collector.md index c35597eb855d8..aad9562944324 100644 --- a/docs/core/run-time-config/garbage-collector.md +++ b/docs/core/run-time-config/garbage-collector.md @@ -28,7 +28,6 @@ Use the following settings to select flavors of garbage collection: - Configures whether the application uses workstation garbage collection or server garbage collection. - Default: Workstation garbage collection (`false`). -- For more information, see [Configure garbage collection](../../standard/garbage-collection/fundamentals.md#configuring-garbage-collection). | | Setting name | Values | Version introduced | | - | - | - | - | diff --git a/docs/framework/configure-apps/file-schema/runtime/gccpugroup-element.md b/docs/framework/configure-apps/file-schema/runtime/gccpugroup-element.md index fe418a16b4a7c..09fc5c80adf92 100644 --- a/docs/framework/configure-apps/file-schema/runtime/gccpugroup-element.md +++ b/docs/framework/configure-apps/file-schema/runtime/gccpugroup-element.md @@ -12,7 +12,7 @@ Specifies whether garbage collection supports multiple CPU groups. [**\**](../configuration-element.md)\   [**\**](runtime-element.md)\ -    **\** +    **\** ## Syntax diff --git a/docs/standard/garbage-collection/fundamentals.md b/docs/standard/garbage-collection/fundamentals.md index 11a57133c0801..63af527230a6a 100644 --- a/docs/standard/garbage-collection/fundamentals.md +++ b/docs/standard/garbage-collection/fundamentals.md @@ -1,22 +1,22 @@ --- -title: "Fundamentals of garbage collection" -description: "Learn how the garbage collector works and how it can be configured for optimum performance." -ms.date: "03/08/2018" +title: Fundamentals of garbage collection +description: Learn how the garbage collector works and how it can be configured for optimum performance. +ms.date: 11/15/2019 ms.technology: dotnet-standard helpviewer_keywords: - "garbage collection, generations" - - "garbage collection, background garbage collection" - - "garbage collection, concurrent garbage collection" - - "garbage collection, server garbage collection" - - "garbage collection, workstation garbage collection" + - "garbage collection, background" + - "garbage collection, concurrent" + - "garbage collection, server" + - "garbage collection, workstation" - "garbage collection, managed heap" ms.assetid: 67c5a20d-1be1-4ea7-8a9a-92b0b08658d2 --- # Fundamentals of garbage collection -In the common language runtime (CLR), the garbage collector serves as an automatic memory manager. It provides the following benefits: +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 for objects you create. +- Enables you to develop your application without having to manually free memory. - Allocates objects on the managed heap efficiently. @@ -24,19 +24,19 @@ In the common language runtime (CLR), the garbage collector serves as an automat - Provides memory safety by making sure that an object cannot use the content of another object. - This topic describes the core concepts of garbage collection. +This article describes the core concepts of garbage collection. ## Fundamentals of memory 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 share the page file if there is one. +- 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. - 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. - If you are writing native code, you use Win32 functions to work with the virtual address space. These functions allocate and free virtual memory for you on native heaps. + 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: @@ -48,15 +48,15 @@ The following list summarizes important CLR memory concepts. - 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. 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 you run out of virtual address space to reserve or physical space to commit. +- You can run out of memory if there isn't enough virtual address space to reserve or physical space to commit. -Your page file is used even if physical memory pressure (that is, demand for physical memory) is low. The first time your 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 is needed, so it is possible to encounter paging in situations where the physical memory pressure is very low. + 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. This is detected by either the low memory notification from the OS or low memory indicated by the host. +- The system has low physical memory. 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. @@ -68,7 +68,7 @@ After the garbage collector is initialized by the CLR, it allocates a segment of There is a managed heap for each managed process. All threads in the process allocate memory for objects on the same heap. -To reserve memory, the garbage collector calls the Win32 [VirtualAlloc](/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc) function, and reserves one segment of memory at a time for managed applications. 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 Win32 [VirtualFree](/windows/desktop/api/memoryapi/nf-memoryapi-virtualfree) function. +To reserve memory, the garbage collector calls the Windows [VirtualAlloc](/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc) function and reserves one segment of memory at a time for managed applications. 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](/windows/desktop/api/memoryapi/nf-memoryapi-virtualfree) function. > [!IMPORTANT] > 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. @@ -83,27 +83,30 @@ The heap can be considered as the accumulation of two heaps: the [large object h The [large object heap](large-object-heap.md) 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. +> [!TIP] +> You can [configure the threshold size](../../core/run-time-config/garbage-collector.md#large-object-heap-threshold) 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: - **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. - Newly allocated objects form a new generation of objects and are implicitly generation 0 collections, unless they are large objects, in which case they go on the large object heap in a generation 2 collection. + Newly allocated objects form a new generation of objects and are implicitly generation 0 collections. However, if they are large objects, they go on the large object heap in a generation 2 collection. Most objects are reclaimed for garbage collection in generation 0 and do not survive to the next generation. - **Generation 1**. This generation contains short-lived objects and serves as a buffer between short-lived objects and long-lived objects. -- **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 is live for the duration of the process. +- **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. 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. 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. +Objects that are not reclaimed in a garbage collection are known as survivors and are promoted to the next generation. 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, so the next collection gets a substantial size of reclaimed memory. The CLR continually balances two priorities: not letting an application's working set get too big by delaying garbage collection and not letting the garbage collection run too frequently. +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. 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 @@ -111,7 +114,7 @@ Because objects in generations 0 and 1 are short-lived, these generations are kn Ephemeral generations must be allocated in the memory segment that is known as the ephemeral segment. Each new segment acquired by the garbage collector becomes the new ephemeral segment and contains the objects that survived a generation 0 garbage collection. The old ephemeral segment becomes the new generation 2 segment. -The size of the ephemeral segment varies depending on whether a system is 32- or 64-bit, and on the type of garbage collector it is running. Default values are shown in the following table. +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-bit|64-bit| |-|-------------|-------------| @@ -136,11 +139,14 @@ A garbage collection has the following phases: Because generation 2 collections can occupy multiple segments, objects that are promoted into generation 2 can be moved into an older segment. Both generation 1 and generation 2 survivors can be moved to a different segment, because they are promoted to generation 2. - Ordinarily, the large object heap is not compacted, because copying large objects imposes a performance penalty. However, starting with the .NET Framework 4.5.1, you can use the property to compact the large object heap on demand. + Ordinarily, the large object heap (LOH) is not compacted, because copying large objects imposes a performance penalty. However, in .NET Core and in .NET Framework 4.5.1 and later, you can use the property to compact the large object heap on demand. In addition, the LOH is automatically compacted when a hard limit is set by specifying either: + + - a memory limit on a container, or + - the [GCHeapHardLimit](../../core/run-time-config/garbage-collector.md#systemgcheaphardlimitcomplus_gcheaphardlimit) or [GCHeapHardLimitPercent](../../core/run-time-config/garbage-collector.md#systemgcheaphardlimitpercentcomplus_gcheaphardlimitpercent) run-time configuration options The garbage collector uses the following information to determine whether objects are live: -- **Stack roots**. Stack variables provided by the just-in-time (JIT) compiler and stack walker. Note that JIT optimizations can lengthen or shorten regions of code within which stack variables are reported to the garbage collector. +- **Stack roots**. Stack variables provided by the just-in-time (JIT) compiler and stack walker. 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. @@ -150,57 +156,43 @@ Before a garbage collection starts, all managed threads are suspended except for The following illustration shows a thread that triggers a garbage collection and causes the other threads to be suspended. -![When a thread triggers a Garbage Collection](../../../docs/standard/garbage-collection/media/gc-triggered.png "When a thread triggers a Garbage Collection") +![When a thread triggers a Garbage Collection](./media/gc-triggered.png) -## Manipulating unmanaged resources +## Manipulate unmanaged resources -If your managed objects reference unmanaged objects by using their native file handles, you have to explicitly free the unmanaged objects, because the garbage collector tracks memory only on the managed heap. +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 your managed object may not dispose the native resources used by the object. To perform the cleanup, you can make your managed object finalizable. Finalization consists of cleanup actions that you execute when the object is no longer in use. When your managed object dies, it performs cleanup actions that are specified in its finalizer method. +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. -## 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. The CLR provides the following types of garbage collection: - -- Workstation garbage collection, which is for all client workstations and stand-alone PCs. This is the default setting for the [\ element](../../../docs/framework/configure-apps/file-schema/runtime/gcserver-element.md) in the runtime configuration schema. - - Workstation garbage collection can be concurrent or non-concurrent. Concurrent garbage collection enables managed threads to continue operations during a garbage collection. - - Starting with the .NET Framework 4, background garbage collection replaces concurrent garbage collection. - -- Server garbage collection, which is intended for server applications that need high throughput and scalability. Server garbage collection can be non-concurrent or background. +For more information about finalization, see . -The following illustration shows the dedicated threads that perform the garbage collection on a server. - -![Server Garbage Collection Threads](../../../docs/standard/garbage-collection/media/gc-server.png "Server Garbage Collection Threads") +## Workstation and server garbage collection -### Configuring garbage collection +The garbage collector is self-tuning and can work in a wide variety of scenarios. You can use a [configuration file setting](../../core/run-time-config/garbage-collector.md#flavors-of-garbage-collection) to set the type of garbage collection based on the characteristics of the workload. The CLR provides the following types of garbage collection: -You can use the [\ element](../../../docs/framework/configure-apps/file-schema/runtime/gcserver-element.md) of the runtime configuration schema to specify the type of garbage collection you want the CLR to perform. When this element's `enabled` attribute is set to `false` (the default), the CLR performs workstation garbage collection. When you set the `enabled` attribute to `true`, the CLR performs server garbage collection. +- Workstation garbage collection (GC) is designed for client apps. It is the default GC flavor for standalone apps. For hosted apps, for example, those hosted by ASP.NET, the host determines the default GC flavor. -Concurrent garbage collection is specified with the [\ element](../../../docs/framework/configure-apps/file-schema/runtime/gcconcurrent-element.md) of the runtime configuration schema. The default setting is `enabled`. This setting controls both concurrent and background garbage collection. + Workstation garbage collection can be concurrent or non-concurrent. Concurrent garbage collection enables managed threads to continue operations during a garbage collection. [Background garbage collection](#background-workstation-garbage-collection) replaces [concurrent garbage collection](#concurrent-garbage-collection) in .NET Framework 4 and later versions. -You can also specify server garbage collection with unmanaged hosting interfaces. Note that ASP.NET and SQL Server enable server garbage collection automatically if your application is hosted inside one of these environments. +- Server garbage collection, which is intended for server applications that need high throughput and scalability. -Starting with .NET Framework 4.6.2, some additional configuration options are available for server garbage collection: + - In .NET Core, server garbage collection can be non-concurrent or background. -- By default, there is an affinity between the server GC heap and a CPU. That is, in server GC, the garbage collector assumes that a process owns the machine on which it is running, so it uses all available CPUs for garbage collection. It creates a dedicated heap, a GC thread, and, if background garbage collection is enabled, a background GC thread for each processor. This can result in poor performance, particularly on systems with multiple running instances of a server application. To not affinitize server GC threads with CPUs, use the [\](../../framework/configure-apps/file-schema/runtime/gcnoaffinitize-element.md) setting in .NET Framework applications. + - In .NET Framework 4.5 and later versions, server garbage collection can be non-concurrent or background (background garbage collection replaces concurrent garbage collection). In .NET Framework 4 and previous versions, server garbage collection is non-concurrent. -- You can limit the number of heaps created by the garbage collector by using the [\](../../framework/configure-apps/file-schema/runtime/gcheapaffinitizemask-element.md) configuration element in .NET Framework applications to control the specific processors for which a GC heap and threads are created. Supply a decimal value. The value is a mask that defines the processors that are available to the process. +![Server Garbage Collection Threads](./media/gc-server.png) -### Comparing workstation and server garbage collection +### 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. 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. +- The collection occurs on the user thread that triggered the garbage collection and remains at the same priority. 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.) - Threads that are running native code are not suspended. - -- Workstation garbage collection is always used on a computer that has only one processor, regardless of the [\](../../../docs/framework/configure-apps/file-schema/runtime/gcserver-element.md) setting. If you specify server garbage collection, the CLR uses workstation garbage collection with concurrency disabled. +- Workstation garbage collection is always used on a computer that has only one processor, regardless of the [configuration setting](../../core/run-time-config/garbage-collector.md#systemgcservercomplus_gcserver). The following are threading and performance considerations for server garbage collection: @@ -210,55 +202,66 @@ The following are threading and performance considerations for server garbage co - 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. Note, however, that this is only a generalization: segment size is implementation-specific and is subject to change. You should make no assumptions about the size of segments allocated by the garbage collector when tuning your app. +- 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. For example, if you have 12 processes running on a computer that has 4 processors, there will be 48 dedicated garbage collection threads if they are all using server garbage collection. In a high memory load situation, if all the processes start doing garbage collection, the garbage collector will have 48 threads to schedule. +- Server garbage collection can be resource-intensive. For example, imagine that there are 12 processes that use server GC running on a computer that has 4 processors. 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. If the processes are active, it's not a good idea to have them all use server GC. -If you are 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. +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. -## Concurrent garbage collection +## Background workstation garbage collection -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. This option affects only garbage collections in generation 2; generations 0 and 1 are always non-concurrent because they finish very fast. +In background workstation garbage collection, ephemeral generations (0 and 1) are collected as needed while the collection of generation 2 is in progress. Background workstation garbage collection is performed on a dedicated thread and applies only to generation 2 collections. -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. +Background garbage collection is enabled by default and can be enabled or disabled with the [gcConcurrent](../../../docs/framework/configure-apps/file-schema/runtime/gcconcurrent-element.md) configuration setting in .NET Framework apps or the [System.GC.Concurrent](../../core/run-time-config/garbage-collector.md#systemgcconcurrentcomplus_gcconcurrent) setting in .NET Core apps. -To improve performance when several processes are running, disable concurrent garbage collection. You can do this by adding a [\ element](../../../docs/framework/configure-apps/file-schema/runtime/gcconcurrent-element.md) to the app's configuration file and setting the value of its `enabled` attribute to `"false"`. +> [!NOTE] +> Background garbage collection replaces [concurrent garbage collection](#concurrent-garbage-collection) and is available in .NET Framework 4 and later versions. In .NET Framework 4, it's supported only for workstation garbage collection. Starting with .NET Framework 4.5, background garbage collection is available for both workstation and server garbage collection. -Concurrent garbage collection is performed on a dedicated thread. By default, the CLR runs workstation garbage collection with concurrent garbage collection enabled. This is true for single-processor and multi-processor computers. +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. -Your ability to allocate small objects on the heap during a concurrent garbage collection is limited by the objects left on the ephemeral segment when a concurrent garbage collection starts. As soon as you reach the end of the segment, you will have to wait for the concurrent garbage collection to finish while managed threads that have to make small object allocations are suspended. +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. -Concurrent garbage collection has a slightly bigger working set (compared with non-concurrent garbage collection), because you can allocate objects during concurrent collection. However, this can affect performance, because the objects that you allocate become part of your working set. Essentially, concurrent garbage collection trades some CPU and memory for shorter pauses. +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. It can also expand the heap if needed during a generation 1 garbage collection. -The following illustration shows concurrent garbage collection performed on a separate dedicated thread. +The following illustration shows background garbage collection performed on a separate dedicated thread on a workstation: -![Concurrent Garbage Collection Threads](../../../docs/standard/garbage-collection/media/gc-concurrent.png "Concurrent Garbage Collection Threads") +![Background workstation garbage collection](./media/fundamentals/background-workstation-garbage-collection.png) -## Background workstation garbage collection +### Background server garbage collection -Background garbage collection replaces concurrent workstation garbage collection starting with the .NET Framework 4, and it replaces concurrent server garbage collection starting with the .NET Framework 4.5. In background garbage collection, ephemeral generations (0 and 1) are collected as needed while the collection of generation 2 is in progress. It is performed on a dedicated thread and is applicable only to generation 2 collections. Background garbage collection is automatically enabled by default, and can be enabled or disabled with the [\](../../../docs/framework/configure-apps/file-schema/runtime/gcconcurrent-element.md) configuration setting in .NET Framework applications. +Starting with .NET Framework 4.5, background server garbage collection is the default mode for server garbage collection. -> [!NOTE] -> Background garbage collection is available only in the .NET Framework 4 and later versions. In the .NET Framework 4, it is supported only for workstation garbage collection. Starting with the .NET Framework 4.5, background garbage collection is available for both workstation and 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: -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. +- 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. -When background garbage collection is in progress and you have 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. +- Unlike the workstation background garbage collection thread, these threads do not time out. -Background garbage collection removes allocation restrictions imposed by concurrent garbage collection, because ephemeral garbage collections can occur during background garbage collection. This means that background garbage collection can remove dead objects in ephemeral generations and 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 server: -The following illustration shows background garbage collection performed on a separate dedicated thread on a workstation: +![Background server garbage collection](./media/fundamentals/background-server-garbage-collection.png) -![Diagram that shows background workstation garbage collection.](./media/fundamentals/background-workstation-garbage-collection.png "Diagram that shows background workstation garbage collection.") +## Concurrent garbage collection -## Background server garbage collection +> [!TIP] +> This section applies to: +> +> - .NET Framework 3.5 and earlier for workstation garbage collection +> - .NET Framework 4 and earlier for server garbage collection +> +> Concurrent garbage is replaced by [background garbage collection](#background-workstation-garbage-collection) in later versions. -Starting with the .NET Framework 4.5, background server garbage collection is the default mode for server garbage collection. To choose this mode, set the `enabled` attribute of the [\ element](../../../docs/framework/configure-apps/file-schema/runtime/gcserver-element.md) to `true` in the runtime configuration schema. This mode 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 a dedicated thread for each logical processor. Unlike the workstation background garbage collection thread, these threads do not time out. +In workstation or server garbage collection, you can [enable concurrent garbage collection](../../../docs/framework/configure-apps/file-schema/runtime/gcconcurrent-element.md), which enables threads to run concurrently with a dedicated thread that performs the garbage collection for most of the duration of the collection. This option affects only garbage collections in generation 2; generations 0 and 1 are always non-concurrent because they finish very fast. -The following illustration shows background garbage collection performed on a separate dedicated thread on a server: +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. 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. -![Diagram that shows background server garbage collection.](./media/fundamentals/background-server-garbage-collection.png "Diagram that shows background server garbage collection.") +![Concurrent Garbage Collection Threads](./media/gc-concurrent.png) ## See also -- [Garbage Collection](../../../docs/standard/garbage-collection/index.md) +- [Configuration options for GC](../../core/run-time-config/garbage-collector.md) +- [Garbage collection](index.md)