diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json index 3ec4287ec8d07..e28096041c81c 100644 --- a/.openpublishing.redirection.json +++ b/.openpublishing.redirection.json @@ -3657,7 +3657,7 @@ }, { "source_path": "docs/standard/garbagecollection/gc.md", - "redirect_url": "/dotnet/standard/garbage-collection/gc" + "redirect_url": "/dotnet/standard/garbage-collection/fundamentals" }, { "source_path": "docs/standard/garbagecollection/implementing-dispose.md", @@ -3687,6 +3687,10 @@ "source_path": "docs/standard/garbagecollection/weak-references.md", "redirect_url": "/dotnet/standard/garbage-collection/weak-references" }, + { + "source_path": "docs/standard/garbage-collection/gc.md", + "redirect_url": "/dotnet/standard/garbage-collection/fundamentals" + }, { "source_path": "docs/standard/garbage-collection/memory-management-and-gc.md", "redirect_url": "/dotnet/standard/garbage-collection/index" diff --git a/docs/core/run-time-config/garbage-collector.md b/docs/core/run-time-config/garbage-collector.md index ea39913f1ab54..37ac358b11b60 100644 --- a/docs/core/run-time-config/garbage-collector.md +++ b/docs/core/run-time-config/garbage-collector.md @@ -18,7 +18,7 @@ Settings are arranged into groups on this page. The settings within each group a ## Flavors of garbage collection -The two main flavors of garbage collection are workstation GC and server GC. For more information about differences between the two, see [Fundamentals of garbage collection](../../standard/garbage-collection/fundamentals.md#workstation-and-server-garbage-collection). +The two main flavors of garbage collection are workstation GC and server GC. For more information about differences between the two, see [Workstation and server garbage collection](../../standard/garbage-collection/workstation-server-gc.md). The subflavors of garbage collection are background and non-concurrent. @@ -66,7 +66,7 @@ Project file: - Configures whether background (concurrent) garbage collection is enabled. - Default: Enabled (`true`). -- For more information, see [Background garbage collection](../../standard/garbage-collection/fundamentals.md#background-workstation-garbage-collection) and [Background server garbage collection](../../standard/garbage-collection/fundamentals.md#background-server-garbage-collection). +- For more information, see [Background garbage collection](../../standard/garbage-collection/background-gc.md). | | Setting name | Values | Version introduced | | - | - | - | - | diff --git a/docs/csharp/programming-guide/classes-and-structs/classes.md b/docs/csharp/programming-guide/classes-and-structs/classes.md index 8ad5e8e20ccd7..dbbc1c661e23d 100644 --- a/docs/csharp/programming-guide/classes-and-structs/classes.md +++ b/docs/csharp/programming-guide/classes-and-structs/classes.md @@ -20,7 +20,7 @@ MyClass mc = new MyClass(); MyClass mc2 = mc; ``` -When the object is created, enough memory is allocated on the managed heap for that specific object, and the variable holds only a reference to the location of said object. Types on the managed heap require overhead both when they are allocated and when they are reclaimed by the automatic memory management functionality of the CLR, which is known as *garbage collection*. However, garbage collection is also highly optimized and in most scenarios, it does not create a performance issue. For more information about garbage collection, see [Automatic memory management and garbage collection](../../../standard/garbage-collection/gc.md). +When the object is created, enough memory is allocated on the managed heap for that specific object, and the variable holds only a reference to the location of said object. Types on the managed heap require overhead both when they are allocated and when they are reclaimed by the automatic memory management functionality of the CLR, which is known as *garbage collection*. However, garbage collection is also highly optimized and in most scenarios, it does not create a performance issue. For more information about garbage collection, see [Automatic memory management and garbage collection](../../../standard/garbage-collection/fundamentals.md). ## Declaring Classes diff --git a/docs/framework/configure-apps/file-schema/runtime/gcconcurrent-element.md b/docs/framework/configure-apps/file-schema/runtime/gcconcurrent-element.md index 9c4a5a86b0afa..835b428d265b5 100644 --- a/docs/framework/configure-apps/file-schema/runtime/gcconcurrent-element.md +++ b/docs/framework/configure-apps/file-schema/runtime/gcconcurrent-element.md @@ -76,7 +76,7 @@ The following configuration file disables background garbage collection: If there's a **gcConcurrentSetting** setting in the machine configuration file, it defines the default value for all .NET Framework applications. The machine configuration file setting overrides the application configuration file setting. -For more information on concurrent and background garbage collection, see the [Concurrent garbage collection](../../../../standard/garbage-collection/fundamentals.md#concurrent-garbage-collection), [Background workstation garbage collection](../../../../standard/garbage-collection/fundamentals.md#background-workstation-garbage-collection), and [Background server garbage collection](../../../../standard/garbage-collection/fundamentals.md#background-server-garbage-collection) sections in the [Fundamentals of Garbage Collection](../../../../standard/garbage-collection/fundamentals.md) article. +For more information on concurrent and background garbage collection, see [Background garbage collection](../../../../standard/garbage-collection/background-gc.md). ## Example 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 09fc5c80adf92..c4a39acbb69eb 100644 --- a/docs/framework/configure-apps/file-schema/runtime/gccpugroup-element.md +++ b/docs/framework/configure-apps/file-schema/runtime/gccpugroup-element.md @@ -73,5 +73,5 @@ The following example shows how to enable garbage collection for multiple CPU gr - [Runtime Settings Schema](index.md) - [Configuration File Schema](../index.md) -- [To disable concurrent garbage collection](gcconcurrent-element.md#to-disable-background-garbage-collection) -- [Workstation and server garbage collection](../../../../standard/garbage-collection/fundamentals.md#workstation-and-server-garbage-collection) +- [Disable concurrent garbage collection](gcconcurrent-element.md#to-disable-background-garbage-collection) +- [Workstation and server garbage collection](../../../../standard/garbage-collection/workstation-server-gc.md) diff --git a/docs/standard/garbage-collection/background-gc.md b/docs/standard/garbage-collection/background-gc.md new file mode 100644 index 0000000000000..60d93910ad940 --- /dev/null +++ b/docs/standard/garbage-collection/background-gc.md @@ -0,0 +1,65 @@ +--- +title: Background garbage collection +description: Learn about background garbage collection in .NET and how it differs in workstation and server garbage collection. +ms.date: 04/21/2020 +helpviewer_keywords: + - garbage collection, background + - background garbage collection +--- +# Background garbage collection + +In background garbage collection (GC), ephemeral generations (0 and 1) are collected as needed while the collection of generation 2 is in progress. Background garbage collection is performed on one or more dedicated threads, depending on whether it's background or server GC, and applies only to generation 2 collections. + +Background garbage collection is enabled by default. It 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. + +> [!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. + +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. + +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 threads 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. It can also expand the heap if needed during a generation 1 garbage collection. + +## Background workstation vs. server GC + +Starting with .NET Framework 4.5, background garbage collection is available for server GC. Background GC is the default mode for server garbage collection. + +Background server garbage collection functions similarly to background workstation garbage collection, 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, the background server GC threads do not time out. + +The following illustration shows background *workstation* garbage collection performed on a separate, dedicated thread: + +![Background workstation garbage collection](./media/fundamentals/background-workstation-garbage-collection.png) + +The following illustration shows background *server* garbage collection performed on separate, dedicated threads: + +![Background server garbage collection](./media/fundamentals/background-server-garbage-collection.png) + +## Concurrent 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 in later versions. + +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 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. By default, the CLR runs workstation garbage collection with concurrent garbage collection enabled on both single-processor and multi-processor computers. + +The following illustration shows concurrent garbage collection performed on a separate dedicated thread. + +![Concurrent Garbage Collection Threads](./media/gc-concurrent.png) + +## See also + +- [Workstation and server garbage collection](workstation-server-gc.md) +- [Run-time configuration options for garbage collection](../../core/run-time-config/garbage-collector.md) diff --git a/docs/standard/garbage-collection/fundamentals.md b/docs/standard/garbage-collection/fundamentals.md index 63af527230a6a..0a9d4cfc71dc8 100644 --- a/docs/standard/garbage-collection/fundamentals.md +++ b/docs/standard/garbage-collection/fundamentals.md @@ -14,18 +14,22 @@ ms.assetid: 67c5a20d-1be1-4ea7-8a9a-92b0b08658d2 --- # Fundamentals of garbage collection -In the common language runtime (CLR), the garbage collector (GC) 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. The garbage collector manages the allocation and release of memory for an application. For developers working with managed code, this means that you don't have to write code to perform memory management tasks. Automatic memory management can eliminate common problems, such as forgetting to free an object and causing a memory leak or attempting to access memory for an object that's already been freed. -- Enables you to develop your application without having to manually free memory. +This article describes the core concepts of garbage collection. + +## Benefits + +The garbage collector provides the following benefits: + +- Frees developers from having to manually release 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. +- 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 don't 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 The following list summarizes important CLR memory concepts. @@ -36,21 +40,37 @@ The following list summarizes important CLR memory concepts. - 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 Windows functions to work with the virtual address space. These functions allocate and free virtual memory for you on native heaps. + If you're 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. + | State | Description | + |---------|---------| + | 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. | - - 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. 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. +- 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, an 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. + +### Memory allocation + +When you initialize a new process, the runtime reserves a contiguous region of address space for the process. This reserved address space is called the managed heap. The managed heap maintains a pointer to the address where the next object in the heap will be allocated. Initially, this pointer is set to the managed heap's base address. All reference types are allocated on the managed heap. When an application creates the first reference type, memory is allocated for the type at the base address of the managed heap. When the application creates the next object, the garbage collector allocates memory for it in the address space immediately following the first object. As long as address space is available, the garbage collector continues to allocate space for new objects in this manner. + +Allocating memory from the managed heap is faster than unmanaged memory allocation. Because the runtime allocates memory for an object by adding a value to a pointer, it's almost as fast as allocating memory from the stack. In addition, because new objects that are allocated consecutively are stored contiguously in the managed heap, an application can access the objects quickly. + +### Memory release + +The garbage collector's optimizing engine determines the best time to perform a collection based on the allocations being made. When the garbage collector performs a collection, it releases the memory for objects that are no longer being used by the application. It determines which objects are no longer being used by examining the application's *roots*. An application's roots include static fields, local variables and parameters on a thread's stack, and CPU registers. Each root either refers to an object on the managed heap or is set to null. The garbage collector has access to the list of active roots that the just-in-time (JIT) compiler and the runtime maintain. Using this list, the garbage collector creates a graph that contains all the objects that are reachable from the roots. + +Objects that are not in the graph are unreachable from the application's roots. The garbage collector considers unreachable objects garbage and releases the memory allocated for them. During a collection, the garbage collector examines the managed heap, looking for the blocks of address space occupied by unreachable objects. As it discovers each unreachable object, it uses a memory-copying function to compact the reachable objects in memory, freeing up the blocks of address spaces allocated to unreachable objects. Once the memory for the reachable objects has been compacted, the garbage collector makes the necessary pointer corrections so that the application's roots point to the objects in their new locations. It also positions the managed heap's pointer after the last reachable object. + +Memory is compacted only if a collection discovers a significant number of unreachable objects. If all the objects in the managed heap survive a collection, then there is no need for memory compaction. + +To improve performance, the runtime allocates memory for large objects in a separate heap. The garbage collector automatically releases the memory for large objects. However, to avoid moving large objects in memory, this memory is usually not compacted. ## Conditions for a garbage collection @@ -58,9 +78,9 @@ 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 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. +- The memory that's used by allocated objects on the managed heap surpasses an acceptable threshold. This threshold is continuously adjusted as the process runs. -- The 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 method is called. In almost all cases, you don't have to call this method, because the garbage collector runs continuously. This method is primarily used for unique situations and testing. ## The managed heap @@ -73,50 +93,66 @@ To reserve memory, the garbage collector calls the Windows [VirtualAlloc](/windo > [!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. -The fewer objects allocated on the heap, the less work the garbage collector has to do. 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. +The fewer objects allocated on the heap, the less work the garbage collector has to do. When you allocate objects, don't 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. +When a garbage collection is triggered, the garbage collector reclaims the memory that's 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](large-object-heap.md) and the small object heap. - -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. +The heap can be considered as the accumulation of two heaps: the [large object heap](large-object-heap.md) and the small object heap. The large object heap contains objects that are 85,000 bytes and larger, which are usually arrays. It's 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: +The GC algorithm is based on several considerations: + +- It's faster to compact the memory for a portion of the managed heap than for the entire managed heap. +- Newer objects have shorter lifetimes and older objects have longer lifetimes. +- Newer objects tend to be related to each other and accessed by the application around the same time. + +Garbage collection primarily occurs with the reclamation of short-lived objects. To optimize the performance of the garbage collector, the managed heap is divided into three generations, 0, 1, and 2, so it can handle long-lived and short-lived objects separately. The garbage collector stores new objects in generation 0. Objects created early in the application's lifetime that survive collections are promoted and stored in generations 1 and 2. Because it's faster to compact a portion of the managed heap than the entire heap, this scheme allows the garbage collector to release the memory in a specific generation rather than release the memory for the entire managed heap each time it performs a collection. - **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. 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. + Most objects are reclaimed for garbage collection in generation 0 and don't survive to the next generation. + + If an application attempts to create a new object when generation 0 is full, the garbage collector performs a collection in an attempt to free address space for the object. The garbage collector starts by examining the objects in generation 0 rather than all objects in the managed heap. A collection of generation 0 alone often reclaims enough memory to enable the application to continue creating new objects. - **Generation 1**. This generation contains short-lived objects and serves as a buffer between short-lived objects and long-lived objects. + After the garbage collector performs a collection of generation 0, it compacts the memory for the reachable objects and promotes them to generation 1. Because objects that survive collections tend to have longer lifetimes, it makes sense to promote them to a higher generation. The garbage collector doesn't have to reexamine the objects in generations 1 and 2 each time it performs a collection of generation 0. + + If a collection of generation 0 does not reclaim enough memory for the application to create a new object, the garbage collector can perform a collection of generation 1, then generation 2. Objects in generation 1 that survive collections are promoted to generation 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. 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). + Objects in generation 2 that survive a collection remain in generation 2 until they are determined to be unreachable in a future collection. + +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 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. +- 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. 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 -Because objects in generations 0 and 1 are short-lived, these generations are known as the ephemeral generations. +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. 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. +Ephemeral generations are allocated in the memory segment that's 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-bit 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 ([workstation or server GC](workstation-server-gc.md)). The following table shows the default sizes of the ephemeral segment. -||32-bit|64-bit| +|Workstation/server GC|32-bit|64-bit| |-|-------------|-------------| |Workstation GC|16 MB|256 MB| |Server GC|64 MB|4 GB| @@ -141,8 +177,8 @@ A garbage collection has the following phases: 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 + - A memory limit on a container. + - 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: @@ -158,110 +194,19 @@ The following illustration shows a thread that triggers a garbage collection and ![When a thread triggers a Garbage Collection](./media/gc-triggered.png) -## 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. - -For more information about finalization, see . - -## 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](../../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: - -- 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. - - 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. - -- Server garbage collection, which is intended for server applications that need high throughput and scalability. - - - In .NET Core, server garbage collection can be non-concurrent or background. - - - 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. - -The following illustration shows the dedicated threads that perform the garbage collection on a server: - -![Server Garbage Collection Threads](./media/gc-server.png) - -### 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. (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](../../core/run-time-config/garbage-collector.md#systemgcservercomplus_gcserver). - -The following are threading and performance considerations for server garbage collection: - -- The collection occurs on multiple dedicated threads that are running at `THREAD_PRIORITY_HIGHEST` priority level. - -- 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. 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'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 - -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. - -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. - -> [!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. - -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. - -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. 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 workstation garbage collection](./media/fundamentals/background-workstation-garbage-collection.png) - -### Background server garbage collection - -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: - -![Background server garbage collection](./media/fundamentals/background-server-garbage-collection.png) - -## Concurrent 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. - -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. +## Unmanaged resources -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. +For most of the objects that your application creates, you can rely on garbage collection to automatically perform the necessary memory management tasks. However, unmanaged resources require explicit cleanup. The most common type of unmanaged resource is an object that wraps an operating system resource, such as a file handle, window handle, or network connection. Although the garbage collector is able to track the lifetime of a managed object that encapsulates an unmanaged resource, it doesn't have specific knowledge about how to clean up the resource. -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. +When you create an object that encapsulates an unmanaged resource, it's recommended that you provide the necessary code to clean up the unmanaged resource in a public `Dispose` method. By providing a `Dispose` method, you enable users of your object to explicitly free its memory when they are finished with the object. When you use an object that encapsulates an unmanaged resource, make sure to call `Dispose` as necessary. -The following illustration shows concurrent garbage collection performed on a separate dedicated thread. +You must also provide a way for your unmanaged resources to be released in case a consumer of your type forgets to call `Dispose`. You can either use a safe handle to wrap the unmanaged resource, or override the method. -![Concurrent Garbage Collection Threads](./media/gc-concurrent.png) +For more information about cleaning up unmanaged resources, see [Clean up unmanaged resources](unmanaged.md). ## See also +- [Workstation and server garbage collection](workstation-server-gc.md) +- [Background garbage collection](background-gc.md) - [Configuration options for GC](../../core/run-time-config/garbage-collector.md) - [Garbage collection](index.md) diff --git a/docs/standard/garbage-collection/gc.md b/docs/standard/garbage-collection/gc.md deleted file mode 100644 index dc3c66578aa80..0000000000000 --- a/docs/standard/garbage-collection/gc.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Automatic memory management and garbage collection -description: Learn how automatic memory management is one of the services that the Common Language Runtime provides during managed execution. -ms.date: 07/22/2016 -ms.technology: dotnet-standard -ms.assetid: d095b0b6-2454-4e23-80b4-c9e8a447116c ---- - -# Automatic memory management and garbage collection - -Automatic memory management is one of the services that the Common Language Runtime provides during managed execution. The Common Language Runtime's garbage collector manages the allocation and release of memory for an application. For developers, this means that you do not have to write code to perform memory management tasks when you develop managed applications. Automatic memory management can eliminate common problems, such as forgetting to free an object and causing a memory leak, or attempting to access memory for an object that has already been freed. This section describes how the garbage collector allocates and releases memory. - -## Allocating Memory - -When you initialize a new process, the runtime reserves a contiguous region of address space for the process. This reserved address space is called the managed heap. The managed heap maintains a pointer to the address where the next object in the heap will be allocated. Initially, this pointer is set to the managed heap's base address. All reference types are allocated on the managed heap. When an application creates the first reference type, memory is allocated for the type at the base address of the managed heap. When the application creates the next object, the garbage collector allocates memory for it in the address space immediately following the first object. As long as address space is available, the garbage collector continues to allocate space for new objects in this manner. - -Allocating memory from the managed heap is faster than unmanaged memory allocation. Because the runtime allocates memory for an object by adding a value to a pointer, it is almost as fast as allocating memory from the stack. In addition, because new objects that are allocated consecutively are stored contiguously in the managed heap, an application can access the objects very quickly. - -## Releasing Memory - -The garbage collector's optimizing engine determines the best time to perform a collection based on the allocations being made. When the garbage collector performs a collection, it releases the memory for objects that are no longer being used by the application. It determines which objects are no longer being used by examining the application's roots. Every application has a set of roots. Each root either refers to an object on the managed heap or is set to null. An application's roots include static fields, local variables and parameters on a thread's stack, and CPU registers. The garbage collector has access to the list of active roots that the just-in-time (JIT) compiler and the runtime maintain. Using this list, it examines an application's roots, and in the process creates a graph that contains all the objects that are reachable from the roots. - -Objects that are not in the graph are unreachable from the application's roots. The garbage collector considers unreachable objects garbage and will release the memory allocated for them. During a collection, the garbage collector examines the managed heap, looking for the blocks of address space occupied by unreachable objects. As it discovers each unreachable object, it uses a memory-copying function to compact the reachable objects in memory, freeing up the blocks of address spaces allocated to unreachable objects. Once the memory for the reachable objects has been compacted, the garbage collector makes the necessary pointer corrections so that the application's roots point to the objects in their new locations. It also positions the managed heap's pointer after the last reachable object. Note that memory is compacted only if a collection discovers a significant number of unreachable objects. If all the objects in the managed heap survive a collection, then there is no need for memory compaction. - -To improve performance, the runtime allocates memory for large objects in a separate heap. The garbage collector automatically releases the memory for large objects. However, to avoid moving large objects in memory, this memory is not compacted. - -## Generations and Performance - -To optimize the performance of the garbage collector, the managed heap is divided into three generations: 0, 1, and 2. The runtime's garbage collection algorithm is based on several generalizations that the computer software industry has discovered to be true by experimenting with garbage collection schemes. First, it is faster to compact the memory for a portion of the managed heap than for the entire managed heap. Secondly, newer objects will have shorter lifetimes and older objects will have longer lifetimes. Lastly, newer objects tend to be related to each other and accessed by the application around the same time. - -The runtime's garbage collector stores new objects in generation 0. Objects created early in the application's lifetime that survive collections are promoted and stored in generations 1 and 2. The process of object promotion is described later in this topic. Because it is faster to compact a portion of the managed heap than the entire heap, this scheme allows the garbage collector to release the memory in a specific generation rather than release the memory for the entire managed heap each time it performs a collection. - -In reality, the garbage collector performs a collection when generation 0 is full. If an application attempts to create a new object when generation 0 is full, the garbage collector discovers that there is no address space remaining in generation 0 to allocate for the object. The garbage collector performs a collection in an attempt to free address space in generation 0 for the object. The garbage collector starts by examining the objects in generation 0 rather than all objects in the managed heap. This is the most efficient approach, because new objects tend to have short lifetimes, and it is expected that many of the objects in generation 0 will no longer be in use by the application when a collection is performed. In addition, a collection of generation 0 alone often reclaims enough memory to allow the application to continue creating new objects. - -After the garbage collector performs a collection of generation 0, it compacts the memory for the reachable objects as explained in [Releasing Memory](#releasing-memory) earlier in this topic. The garbage collector then promotes these objects and considers this portion of the managed heap generation 1. Because objects that survive collections tend to have longer lifetimes, it makes sense to promote them to a higher generation. As a result, the garbage collector does not have to reexamine the objects in generations 1 and 2 each time it performs a collection of generation 0. - -After the garbage collector performs its first collection of generation 0 and promotes the reachable objects to generation 1, it considers the remainder of the managed heap generation 0. It continues to allocate memory for new objects in generation 0 until generation 0 is full and it is necessary to perform another collection. At this point, the garbage collector's optimizing engine determines whether it is necessary to examine the objects in older generations. For example, if a collection of generation 0 does not reclaim enough memory for the application to successfully complete its attempt to create a new object, the garbage collector can perform a collection of generation 1, then generation 2. If this does not reclaim enough memory, the garbage collector can perform a collection of generations 2, 1, and 0. After each collection, the garbage collector compacts the reachable objects in generation 0 and promotes them to generation 1. Objects in generation 1 that survive collections are promoted to generation 2. Because the garbage collector supports only three generations, objects in generation 2 that survive a collection remain in generation 2 until they are determined to be unreachable in a future collection. - -## Releasing Memory for Unmanaged Resources - -For the majority of the objects that your application creates, you can rely on the garbage collector to automatically perform the necessary memory management tasks. However, unmanaged resources require explicit cleanup. The most common type of unmanaged resource is an object that wraps an operating system resource, such as a file handle, window handle, or network connection. Although the garbage collector is able to track the lifetime of a managed object that encapsulates an unmanaged resource, it does not have specific knowledge about how to clean up the resource. When you create an object that encapsulates an unmanaged resource, it is recommended that you provide the necessary code to clean up the unmanaged resource in a public `Dispose` method. By providing a `Dispose` method, you enable users of your object to explicitly free its memory when they are finished with the object. When you use an object that encapsulates an unmanaged resource, you should be aware of `Dispose` and call it as necessary. For more information about cleaning up unmanaged resources and an example of a design pattern for implementing `Dispose`, see [Garbage Collection in .NET](index.md). - -## See also - -- [System.GC](xref:System.GC) -- [Garbage collection in .NET](index.md) diff --git a/docs/standard/garbage-collection/index.md b/docs/standard/garbage-collection/index.md index bd01cf79d7300..1f99bc7d434d9 100644 --- a/docs/standard/garbage-collection/index.md +++ b/docs/standard/garbage-collection/index.md @@ -1,6 +1,6 @@ --- -title: "Garbage Collection" -ms.date: "03/30/2017" +title: .NET garbage collection +ms.date: 04/21/2020 ms.technology: dotnet-standard helpviewer_keywords: - "memory, garbage collection" @@ -19,40 +19,37 @@ helpviewer_keywords: - "garbage collection, about" ms.assetid: 22b6cb97-0c80-4eeb-a2cf-5ed7655e37f9 --- -# Garbage Collection +# Garbage collection + .NET's garbage collector manages the allocation and release of memory for your application. Each time you create a new object, the common language runtime allocates memory for the object from the managed heap. As long as address space is available in the managed heap, the runtime continues to allocate space for new objects. However, memory is not infinite. Eventually the garbage collector must perform a collection in order to free some memory. The garbage collector's optimizing engine determines the best time to perform a collection, based upon the allocations being made. When the garbage collector performs a collection, it checks for objects in the managed heap that are no longer being used by the application and performs the necessary operations to reclaim their memory. - -## Related Topics +## In this section |Title|Description| |-----------|-----------------| -|[Fundamentals of Garbage Collection](../../../docs/standard/garbage-collection/fundamentals.md)|Describes how garbage collection works, how objects are allocated on the managed heap, and other core concepts.| -|[Garbage Collection and Performance](../../../docs/standard/garbage-collection/performance.md)|Describes the performance checks you can use to diagnose garbage collection and performance issues.| -|[Induced Collections](../../../docs/standard/garbage-collection/induced.md)|Describes how to make a garbage collection occur.| -|[Latency Modes](../../../docs/standard/garbage-collection/latency.md)|Describes the modes that determine the intrusiveness of garbage collection.| -|[Optimization for Shared Web Hosting](../../../docs/standard/garbage-collection/optimization-for-shared-web-hosting.md)|Describes how to optimize garbage collection on servers shared by several small Web sites.| -|[Garbage Collection Notifications](../../../docs/standard/garbage-collection/notifications.md)|Describes how to determine when a full garbage collection is approaching and when it has completed.| -|[Application Domain Resource Monitoring](../../../docs/standard/garbage-collection/app-domain-resource-monitoring.md)|Describes how to monitor CPU and memory usage by an application domain.| -|[Weak References](../../../docs/standard/garbage-collection/weak-references.md)|Describes features that permit the garbage collector to collect an object while still allowing the application to access that object.| - -## Reference - - - - - - - - - - - - - - - +|[Fundamentals of garbage collection](../../../docs/standard/garbage-collection/fundamentals.md)|Describes how garbage collection works, how objects are allocated on the managed heap, and other core concepts.| +|[Workstation and server garbage collection](workstation-server-gc.md)|Describes the differences between workstation garbage collection for client apps and server garbage collection for server apps.| +|[Background garbage collection](background-gc.md)|Describes background garbage collection, which is the collection of generation 0 and 1 objects while generation 2 collection is in progress.| +|[The large object heap](large-object-heap.md)|Describes the large object heap (LOH) and how large objects are garbage-collected.| +|[Garbage collection and performance](../../../docs/standard/garbage-collection/performance.md)|Describes the performance checks you can use to diagnose garbage collection and performance issues.| +|[Induced collections](../../../docs/standard/garbage-collection/induced.md)|Describes how to make a garbage collection occur.| +|[Latency modes](../../../docs/standard/garbage-collection/latency.md)|Describes the modes that determine the intrusiveness of garbage collection.| +|[Optimization for shared web hosting](../../../docs/standard/garbage-collection/optimization-for-shared-web-hosting.md)|Describes how to optimize garbage collection on servers shared by several small Web sites.| +|[Garbage collection notifications](../../../docs/standard/garbage-collection/notifications.md)|Describes how to determine when a full garbage collection is approaching and when it has completed.| +|[Application domain resource monitoring](../../../docs/standard/garbage-collection/app-domain-resource-monitoring.md)|Describes how to monitor CPU and memory usage by an application domain.| +|[Weak references](../../../docs/standard/garbage-collection/weak-references.md)|Describes features that permit the garbage collector to collect an object while still allowing the application to access that object.| + +## Reference + +- +- +- +- +- +- +- +- ## See also -- [Cleaning Up Unmanaged Resources](../../../docs/standard/garbage-collection/unmanaged.md) +- [Clean up unmanaged resources](../../../docs/standard/garbage-collection/unmanaged.md) diff --git a/docs/standard/garbage-collection/large-object-heap.md b/docs/standard/garbage-collection/large-object-heap.md index ef138836977de..9401bdd507f43 100644 --- a/docs/standard/garbage-collection/large-object-heap.md +++ b/docs/standard/garbage-collection/large-object-heap.md @@ -1,6 +1,6 @@ --- -title: LOH on Windows - .NET -ms.date: "05/02/2018" +title: Large object heap (LOH) on Windows +ms.date: 05/02/2018 helpviewer_keywords: - large object heap (LOH)" - LOH @@ -9,18 +9,18 @@ helpviewer_keywords: --- # The large object heap on Windows systems -The .NET Garbage Collector (GC) divides objects up into small and large objects. When an object is large, some of its attributes become more significant than if the object is small. For instance, compacting it -- that is, copying it in memory elsewhere on the heap -- can be expensive. Because of this, the .NET Garbage Collector places large objects on the large object heap (LOH). In this topic, we'll look at the large object heap in depth. We'll discuss what qualifies an object as a large object, how these large objects are collected, and what kind of performance implications large objects impose. +The .NET garbage collector (GC) divides objects up into small and large objects. When an object is large, some of its attributes become more significant than if the object is small. For instance, compacting it—that is, copying it in memory elsewhere on the heap—can be expensive. Because of this, the garbage collector places large objects on the large object heap (LOH). This article discusses what qualifies an object as a large object, how large objects are collected, and what kind of performance implications large objects impose. > [!IMPORTANT] -> This topic discusses the large object heap in the .NET Framework and .NET Core running on Windows systems only. It does not cover the LOH running on .NET implementations on other platforms. +> This article discusses the large object heap in .NET Framework and .NET Core running on Windows systems only. It does not cover the LOH running on .NET implementations on other platforms. -## How an object ends up on the large object heap and how GC handles them +## How an object ends up on the LOH If an object is greater than or equal to 85,000 bytes in size, it’s considered a large object. This number was determined by performance tuning. When an object allocation request is for 85,000 or more bytes, the runtime allocates it on the large object heap. -To understand what this means, it's useful to examine some fundamentals about the .NET GC. +To understand what this means, it's useful to examine some fundamentals about the garbage collector. -The .NET Garbage Collector is a generational collector. It has three generations: generation 0, generation 1, and generation 2. The reason for having 3 generations is that, in a well-tuned app, most objects die in gen0. For example, in a server app, the allocations associated with each request should die after the request is finished. The in-flight allocation requests will make it into gen1 and die there. Essentially, gen1 acts as a buffer between young object areas and long-lived object areas. +The garbage collector is a generational collector. It has three generations: generation 0, generation 1, and generation 2. The reason for having 3 generations is that, in a well-tuned app, most objects die in gen0. For example, in a server app, the allocations associated with each request should die after the request is finished. The in-flight allocation requests will make it into gen1 and die there. Essentially, gen1 acts as a buffer between young object areas and long-lived object areas. Small objects are always allocated in generation 0 and, depending on their lifetime, may be promoted to generation 1 or generation2. Large objects are always allocated in generation 2. @@ -58,7 +58,7 @@ Figure 3: The LOH after a generation 2 GC ## When is a large object collected? -In general, a GC occurs when one of the following 3 conditions happens: +In general, a GC occurs under one of the following three conditions: - Allocation exceeds the generation 0 or large object threshold. @@ -74,7 +74,7 @@ In general, a GC occurs when one of the following 3 conditions happens: This occurs when the garbage collector receives a high memory notification from the OS. If the garbage collector thinks that doing a generation 2 GC will be productive, it triggers one. -## LOH Performance Implications +## LOH performance implications Allocations on the large object heap impact performance in the following ways. @@ -116,7 +116,7 @@ Allocations on the large object heap impact performance in the following ways. Out of the three factors, the first two are usually more significant than the third. Because of this, we recommend that you allocate a pool of large objects that you reuse instead of allocating temporary ones. -## Collecting performance data for the LOH +## Collect performance data for the LOH Before you collect performance data for a specific area, you should already have done the following: @@ -304,6 +304,6 @@ This command breaks into the debugger and shows the call stack only if [VirtualA CLR 2.0 added a feature called *VM Hoarding* that can be useful for scenarios where segments (including on the large and small object heaps) are frequently acquired and released. To specify VM Hoarding, you specify a startup flag called `STARTUP_HOARD_GC_VM` via the hosting API. Instead of releasing empty segments back to the OS, the CLR decommits the memory on these segments and puts them on a standby list. (Note that the CLR doesn't do this for segments that are too large.) The CLR later uses those segments to satisfy new segment requests. The next time that your app needs a new segment, the CLR uses one from this standby list if it can find one that’s big enough. -VM hoarding is also useful for applications that want to hold onto the segments that they already acquired, such as some server apps that are the dominant apps running on the system, to avoid out of memory exceptions. +VM hoarding is also useful for applications that want to hold onto the segments that they already acquired, such as some server apps that are the dominant apps running on the system, to avoid out-of-memory exceptions. We strongly recommend that you carefully test your application when you use this feature to ensure your application has fairly stable memory usage. diff --git a/docs/standard/garbage-collection/workstation-server-gc.md b/docs/standard/garbage-collection/workstation-server-gc.md new file mode 100644 index 0000000000000..0c0791d48f91c --- /dev/null +++ b/docs/standard/garbage-collection/workstation-server-gc.md @@ -0,0 +1,58 @@ +--- +title: Workstation vs. server garbage collection (GC) +description: Learn about workstation and server garbage collection in .NET. +ms.date: 04/21/2020 +helpviewer_keywords: + - garbage collection, workstation + - garbage collection, server + - workstation garbage collection + - server garbage collection +--- +# Workstation and server garbage collection + +The garbage collector is self-tuning and can work in a wide variety of scenarios. However, you can [set the type of garbage collection](../../core/run-time-config/garbage-collector.md#flavors-of-garbage-collection) based on the characteristics of the workload. The CLR provides the following types of garbage collection: + +- Workstation garbage collection (GC), which is designed for client apps. It's the default GC flavor for standalone apps. 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 (or *background*) garbage collection enables managed threads to continue operations during a garbage collection. [Background garbage collection](background-gc.md) replaces [concurrent garbage collection](background-gc.md#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. + + - In .NET Core, server garbage collection can be non-concurrent or background. + + - In .NET Framework 4.5 and later versions, server garbage collection can be non-concurrent or background. 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: + +![Server Garbage Collection Threads](./media/gc-server.png) + +## Performance considerations + +### Workstation GC + +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. (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](../../core/run-time-config/garbage-collector.md#systemgcservercomplus_gcserver). + +### Server GC + +The following are threading and performance considerations for server garbage collection: + +- The collection occurs on multiple dedicated threads that are running at `THREAD_PRIORITY_HIGHEST` priority level. + +- 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. For example, imagine that there are 12 processes that use server GC running on a computer that has four 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'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. + +## See also + +- [Background garbage collection](background-gc.md) +- [Run-time configuration options for garbage collection](../../core/run-time-config/garbage-collector.md) diff --git a/docs/standard/toc.yml b/docs/standard/toc.yml index acf8c72bf6aa1..06a57580a83db 100644 --- a/docs/standard/toc.yml +++ b/docs/standard/toc.yml @@ -232,7 +232,11 @@ displayName: garbage collection - name: Fundamentals href: garbage-collection/fundamentals.md - - name: The Large Object Heap + - name: Workstation and server GC + href: garbage-collection/workstation-server-gc.md + - name: Background GC + href: garbage-collection/background-gc.md + - name: The large object heap href: garbage-collection/large-object-heap.md - name: Garbage collection and performance href: garbage-collection/performance.md