Skip to content

Commit 920cf5b

Browse files
committed
add: managed heap
1 parent d889fbd commit 920cf5b

2 files changed

Lines changed: 67 additions & 3 deletions

File tree

src/content/posts/NET/Heap/Heap.md

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,74 @@
11
---
22
title: "CLR Managed Heaps In .NET"
3-
published: 2025-08-04
3+
published: 2025-08-10
44
description: "Some notes during the time i study CLR Managed Heap.NET"
55
image: "./heapAreaView.svg"
66
tags: [DOTNET, CSharp]
77
category: "DOTNET"
88
draft: false
99
lang: "en"
1010
---
11+
12+
# Understanding CLR Managed Heaps in .NET
13+
14+
The Common Language Runtime (CLR) is the heart of the .NET ecosystem, responsible for managing the execution of .NET applications. One of its critical components is memory management, which is handled through various heaps. These heaps are specialized memory regions designed to optimize performance, garbage collection, and resource allocation. In this article, we delve into two primary categories: Loader Heaps and Managed Heaps. We'll explore their subcomponents, purposes, and how they contribute to efficient .NET application runtime.
15+
16+
## Loader Heaps
17+
18+
Loader Heaps are part of the CLR's internal memory management system, primarily used for storing metadata, code, and other runtime structures that are not subject to garbage collection. These heaps are created and managed by the CLR loader, which is responsible for loading assemblies, types, and methods. Unlike managed heaps, loader heaps are not generational and grow monotonically until the process terminates. They are divided into several specialized sub-heaps to handle different types of data with varying allocation frequencies and lifetimes.
19+
20+
### High Frequency Heap
21+
22+
The High Frequency Heap is optimized for frequent allocations of small, short-lived objects. It is used for structures that are created and discarded rapidly during the CLR's operation, such as temporary buffers or small metadata entries. This heap employs a fast allocation mechanism to minimize overhead, ensuring that high-throughput operations like method invocations or type resolutions do not bottleneck the system.
23+
24+
### Low Frequency Heap
25+
26+
In contrast, the Low Frequency Heap handles allocations that occur less often but may involve larger or longer-lived objects. This includes assembly metadata, module information, and other static data that persists for the duration of the application domain. By segregating these from high-frequency allocations, the CLR reduces fragmentation and improves cache locality.
27+
28+
### Stub Heap
29+
30+
The Stub Heap is dedicated to storing stubs, which are small pieces of code that act as intermediaries for method calls. These include thunks for P/Invoke calls, delegate invocations, and interface dispatch. Stubs are generated dynamically and stored here to facilitate seamless transitions between managed and unmanaged code or to handle virtual method resolutions efficiently.
31+
32+
### JIT Heap
33+
34+
The Just-In-Time (JIT) Heap stores compiled native code generated by the JIT compiler. When managed methods are executed for the first time, the CLR compiles IL (Intermediate Language) to machine code and allocates space for it in this heap. This heap is crucial for performance, as it holds the executable instructions that run the application. It grows as more methods are JIT-compiled, and the code remains valid until the application domain is unloaded.
35+
36+
### VCS Heap
37+
38+
The Version Control System (VCS) Heap, also known as the Version-Compatible Serialization Heap, manages data related to serialization and deserialization processes that require version tolerance. It stores type information and serializers for objects that need to be persisted or transmitted across different .NET versions, ensuring compatibility and backward/forward serialization support.
39+
40+
### Process/Base Heap
41+
42+
The Process/Base Heap serves as the foundational heap for the CLR process. It allocates memory for core runtime structures, such as the execution engine, thread pools, and global variables. This heap is initialized early in the process lifetime and provides the base memory pool from which other loader heaps may derive or reference. It is essential for the overall stability and initialization of the CLR environment.
43+
44+
## Managed Heaps
45+
46+
Managed Heaps are the core of .NET's garbage-collected memory management. Objects created by managed code (e.g., via `new` in C#) are allocated on these heaps. The Garbage Collector (GC) periodically reclaims memory from unreachable objects, compacting the heaps to reduce fragmentation. Managed heaps are generational, dividing objects based on their lifetimes to optimize collection efficiency. The primary managed heaps include the Small Object Heap (SOH), Large Object Heap (LOH), Pinned Object Heap (POH), and Frozen Object Heap (FOH).
47+
48+
### Small Object Heap (SOH)
49+
50+
The Small Object Heap is designed for objects smaller than 85 KB. It is divided into three generations:
51+
52+
- **Generation 0**: For newly allocated objects. Collections here are frequent and fast, targeting short-lived objects.
53+
- **Generation 1**: Acts as a buffer between Gen 0 and Gen 2. Objects surviving Gen 0 collections are promoted here.
54+
- **Generation 2**: For long-lived objects. Collections are less frequent but more expensive, involving the entire heap.
55+
56+
The generational approach assumes most objects die young, allowing the GC to focus on smaller portions of the heap.
57+
58+
### Large Object Heap (LOH)
59+
60+
The Large Object Heap accommodates objects 85 KB or larger, such as large arrays or buffers. Unlike the SOH, the LOH is not compacted by default in workstation GC mode to avoid high CPU costs, though server GC mode supports compaction in .NET Framework 4.5+. Objects here are always considered Generation 2, and collections occur during full GCs. Fragmentation can be an issue, mitigated by techniques like object pooling.
61+
62+
### Pinned Object Heap (POH)
63+
64+
Introduced in .NET 5, the Pinned Object Heap is for objects that are pinned in memory (e.g., via `fixed` keyword or GCHandle). Pinning prevents the GC from moving objects during compaction, which is necessary for interop with unmanaged code. The POH segregates these objects to minimize fragmentation in other heaps, improving overall GC performance. Pinned objects are allocated here if the allocation requests pinning.
65+
66+
### Frozen Object Heap (FOH)
67+
68+
The Frozen Object Heap, available in .NET 8 and later, is optimized for immutable, long-lived objects that are never modified after creation. Examples include string literals or static readonly fields. Objects on the FOH are not subject to garbage collection once frozen, reducing GC overhead. This heap enhances performance in scenarios with many static or cached immutable data structures, as it allows the runtime to skip these during collections.
69+
70+
## Conclusion
71+
72+
Understanding the CLR's Loader Heaps and Managed Heaps is essential for .NET developers aiming to optimize memory usage and performance. By leveraging the specialized nature of these heaps, applications can achieve better scalability and efficiency. For deeper insights, consider profiling tools like dotnet-trace or Visual Studio's Performance Profiler to observe heap behavior in real-world scenarios.
73+
74+
Whether you're debugging memory leaks or tuning GC settings, a solid grasp of these concepts will empower you to write more robust .NET code.

0 commit comments

Comments
 (0)