Збирач сміття (Garbage Collector, GC) у .NET продовжує еволюціонувати, забезпечуючи ефективне керування пам'яттю в умовах сучасних хмарних і контейнеризованих середовищ. У .NET 10, випущеній у листопаді 2025 року, ключовими інноваціями стали розширені налаштування DATAS (Dynamic Adaptation to Application Sizes) для Server GC, оптимізації ескейп-аналізу для стекових алокацій малих об'єктів, елімінація write-barrier'ів та покращення для Arm64. Ці зміни зменшують тиск на GC, знижуючи латентність на 66–91%, елімінуючи алокації в 100% випадків для короткоживучих об'єктів та стабілізуючи паузи під навантаженням. На основі документації Microsoft та бенчмарків, демонструється скорочення memory footprint на 70–90% у мікросервісах та зростання throughput на 10–18%. Стаття корисна для розробників високонавантажених систем, особливо в Kubernetes та Azure, з рекомендаціями щодо тюнінгу.
Ключові слова: .NET 10, Garbage Collector, DATAS, стекові алокації, write-barrier, Arm64, продуктивність, латентність.
Розвиток GC у .NET від Workstation/Server режимів у ранніх версіях до адаптивних моделей у .NET Core еволюціонував з фокусом на кросплатформенність та оптимізацію для хмар. .NET 9 ввела DATAS за замовчуванням, але .NET 10 робить крок далі, інтегруючи JIT-оптимізації для зменшення алокацій та динамічне керування heap'ом. Це критично для додатків з флуктуаціями навантаження, де традиційний Server GC може призводити до надмірного споживання ресурсів або нестабільних пауз.
За даними Microsoft, оптимізації .NET 10 знижують алокації на 73–100% у типових сценаріях (наприклад, делегати та малі масиви) та стабілізують throughput на 10–18% у TechEmpower. Стаття розгляне DATAS-розширення, стекові алокації, write-barrier оптимізації та інші фішки, з прикладами, бенчмарками та порадами.
GC у .NET базується на поколінному підході: Gen0 для короткоживучих об'єктів, Gen1/Gen2 для довгоживучих, LOH для великих. Server GC використовує паралельні heap'и на ядро, але в .NET 10 акцент на адаптивності: DATAS динамічно налаштовує розмір heap за live data size (LDS), а JIT елімінує непотрібні алокації через ескейп-аналіз. Write-barrier'и оптимізовані для Arm64, зменшуючи overhead на 8–20%. Це інтегровано з runtime для меншого тиску на GC, особливо в контейнерах.
DATAS, активована за замовчуванням у .NET 9, у .NET 10 еволюціонує для Server GC: автоматично регулює кількість heap'ів (від 1 до core count), обчислює бюджет Gen0 через Budget Computed via DATAS (BCD) на основі LDS та promoted bytes. Вводиться Throughput Cost Percentage (TCP) – ціль 2% пауз для балансу. Heap росте/зменшується динамічно, уникаючи фіксованих розмірів, що корисно в контейнерах (e.g., 256 MB limits). Консервативний режим (conserve memory) впливає на full GC, але ephemeral GC залишаються гнучкими.
Тести демонструють стабільні heap sizes незалежно від core count, з меншими паузами під навантаженням.
| Сценарій | .NET 9 (DATAS) | .NET 10 (Enhanced DATAS) | Покращення |
|---|---|---|---|
| Max heap size (12-core) | 1.2 GB | 800 MB | -33% |
| Max heap size (28-core) | 2.5 GB | 850 MB | -66% |
| Throughput regression | 6–7% | 2–3% (з тюнінгом) | -60% |
| Pause time variability | Висока | Низька (під load) | Стабілізація |
Джерело: Бенчмарки Microsoft ASP.NET. У хмарних сценаріях – скорочення cloud costs на 20–30% за рахунок динамічного релізу пам'яті.
У ASP.NET Core API з bursty load: без DATAS heap стрибає до 2 GB; з .NET 10 – стабільно 800 MB, з tuning GCDGen0GrowthPercent=2.6. Конфіг:
{
"runtimeOptions": {
"configProperties": {
"System.GC.DynamicAdaptationMode": 1,
"System.GC.GCDGen0GrowthPercent": 2600
}
}
}
Тест у Minikube: 40% менше подій GC, але коротші паузи.
.NET 10 розширює ескейп-аналіз у JIT: малі масиви, делегати (Func/Action) та Span в structs алокуються на стеку, якщо не ескейплять метод. Це елімінує heap алокації для короткоживучих об'єктів, зменшуючи GC pressure на 73–100%. Нові типи GCHandle (Pinned/Weak) додають type-safety та RAII.
Ключові фішки:
- Delegate stack allocation: Якщо не capture this.
- Small array stack: Для int[]/string[] < escape.
- Span reasoning: Для buffer ops.
| Сценарій | .NET 9 | .NET 10 | Покращення |
|---|---|---|---|
| Delegate latency | 19.5 ns, 88 B | 6.7 ns, 24 B | -66% latency, -73% alloc |
| Small array | 11.6 ns, 48 B | 4.0 ns, 0 B | -66% latency, -100% alloc |
| Span copy | 9.8 ns, 32 B | 0.9 ns, 0 B | -91% latency, -100% alloc |
| GCHandle pin | 27.8 ns | 22.7 ns | -18% |
Джерело: JIT benchmarks. У LINQ-heavy apps – +15% throughput.
Стандартно активовано; тюнінг не потрібен, але моніторте через dotnet-counters. Приклад коду:
public int SumSmallArray()
{
int[] nums = [1, 2, 3]; // Stack in .NET 10
return nums.Sum();
}Рекомендація: Використовуйте local functions замість lambdas для уникнення ескейпу.
Write-barrier'и (для cross-gen refs) оптимізовані: JIT елімінує в ref struct fields та return buffers, зменшуючи code size на 57–58%. На Arm64 – dynamic switching між impl'ами via WriteBarrierManager, з новим default для precise GC regions. Це trade-off: + slight write cost, але -8–20% GC pauses.
Паралельна компакція LOH покращена, зменшуючи фрагментацію.
| Сценарій | .NET 9 | .NET 10 (Arm64) | Покращення |
|---|---|---|---|
| GC pause time | Базовий | 8–20% менше | -20% max |
| Code size (ref struct) | 59 B | 25 B | -58% |
| Write throughput | Базовий | Slight - , але net gain | Стабілізація |
У контейнерах – менший card table pollution.
Автоматично; для legacy – DOTNET_GCDynamicAdaptationMode=0. Рекомендація: Тестуйте на Arm64 для IoT/edge.
Region-based heap (з .NET 7) тюнінгується: RegionSize (4 MB default), RegionRange (512 GB). HeapHardLimit для контейнерів запобігає OOM. LOHThreshold (120 KB) зменшує фрагментацію.
JIT: Devirtualization для IEnumerable, inlining для structs. Приклад:
var handle = new PinnedGCHandle<byte[]>(array).Dispose(); // 18% швидшеЗнижує алокації в DI та reflection на 15–25%.
Оптимізації GC у .NET 10 – від розширеної DATAS до стекових алокацій – роблять платформу гнучкішою для хмар та edge, з -91% латентності, -100% алокацій у ключових сценаріях та стабільними паузами. Переваги перевищують мінімальні регресії (2–3% throughput з тюнінгом). Оновлюйте, тестуйте з BenchmarkDotNet, моніторте dotnet-counters. Майбутнє – AI-передбачення алокацій та NativeAOT інтеграція.
- Microsoft. (2025). What's new in .NET 10 runtime.
- Microsoft. (2025). Performance Improvements in .NET 10.
- Maoni Stephens. (2025). Preparing for the .NET 10 GC.
- Roxeem. (2025). What .NET 10 GC Changes Mean for Developers.
- Microsoft. (2025). Announcing .NET 10.