Dynamic adaptation to application sizes (DATAS) GC 策略

现在大家的 .NET 程序基本都部署在如 K8S 这种容器化场景下。出于节约资源的考虑,往往我们还会限制每个实例占用的资源。不知道大家发现没有,在一些高并发的场景下,我们的程序会占用非常多的内存,内存迟迟不释放,在某些极端情况下甚至会发生 OOM 。如果你搜索这个问题,大概率会找到一个答案,那就是在一些资源有限的环境请把 GC 改成 workstation 模式。更改为 workstation 模式后,内存占用高的情况确实有所好转,但是同时也会影响服务的吞吐量。

到了 .NET8 其实我们还有另外一个 GC 的策略可以选择,那就是 DATAS - Dynamic adaptation to application sizes 。它可以帮我们在内存占用跟吞吐量之间找到一个平衡。

首先让我们回顾一下什么是 Workstation 跟 Server GC。

Workstation GC

工作站垃圾回收(Workstation GC)

定位:专为客户端应用程序设计

  • 默认场景:

独立应用程序的默认GC类型

托管应用(如ASP.NET托管的应用)由宿主决定默认类型

  • 运行模式:

并发模式(Concurrent GC):允许托管线程在垃圾回收期间继续运行(.NET Framework 4及后续版本中由后台GC取代)

非并发模式:执行垃圾回收时会暂停所有托管线程

Server GC

服务器垃圾回收(Server GC)

核心优势:为需要高吞吐量和高可扩展性的服务端应用程序优化

  • 典型特征:

为每个逻辑CPU创建独立GC堆

采用更激进的堆扩展策略

适用于多核服务器环境

DATAS

了解了 Workstation 与 Server GC 的概念后,让我们看看 DATAS 是怎么工作的。

动态适应应用规模的垃圾回收机制(DATAS GC)旨在根据应用程序的内存需求进行自适应调整。这意味着应用程序堆大小应与长期存活数据量大致成正比。如果在不同配置的机器上运行相同任务,堆大小应保持相同或相近;当工作负载减轻或加重时,堆大小会相应调整。

与之相比,服务器GC模式(Server GC)以提升吞吐量为目标,假设当前进程是机器上的主导进程。其触发下次GC前的分配量基于吞吐量而非应用规模。只要内存可用,它会激进地扩展堆空间,导致相同进程在不同硬件配置的机器上运行时堆大小差异显著(例如在核心数和内存更多的机器上堆会大幅增长)。即使工作负载大幅减轻,服务器GC也不一定会主动缩减堆空间。

DATAS GC尤其适合突发型工作负载,能根据负载需求(特别是需求下降时)调整堆大小。这对内存受限环境至关重要------当某些进程负载降低时可容纳更多进程,同时也利于容量规划。该功能在.NET 8中作为可选特性引入,并在.NET 9默认启用。

实现原理

为实现应用规模自适应且保持性能,DATAS GC采取以下策略:

基于长期存活数据量设定触发下次GC前的最大分配量,从而约束堆大小

基于吞吐量动态调整实际允许的分配量

弹性调整堆数量:初始仅使用单堆(多线程分配时可能引发等待,影响吞吐量),但会根据需求增减堆数量。这种混合模式兼具工作站GC(单堆)和服务器GC(按核心数分配堆)的优势

执行完全压缩式GC以防止内存碎片过高,进一步帮助控制堆大小

关注我的公众号一起玩转技术

相关推荐
ahxdyz2 小时前
.NET平台MCP
ai·.net·mcp
の天命喵星人3 小时前
.net 使用NLog记录日志
.net
绿荫阿广4 小时前
将SignalR移植到Esp32—让小智设备无缝连接.NET功能拓展MCP服务
.net·asp.net core·mcp
有来技术9 小时前
ASP.NET Core 权限管理系统(RBAC)设计与实现|vue3-element-admin .NET 后端
vue.js·后端·c#·asp.net·.net
云草桑10 小时前
15分钟快速了解 Odoo
数据库·python·docker·postgresql·.net·odoo
Traced back11 小时前
SQL Server数据自动清理系统最终版(C# WinForms完整源码)
数据库·c#·.net
初九之潜龙勿用1 天前
C# 操作Word模拟解析HTML标记之背景色
开发语言·c#·word·.net·office
时光追逐者1 天前
使用 MWGA 帮助 7 万行 Winforms 程序快速迁移到 WEB 前端
前端·c#·.net
程序猿小玉兒1 天前
解决大文件上传失败问题
c#·.net
GfhyPpNY1 天前
信号交叉口联网燃料电池混合动力汽车生态驾驶的双层凸优化探索
.net