GC Committed Bytes含义解析及ASP.NET Core内存排查咨询
内存分析问题解答:GC Committed Bytes异常与排查步骤
一、GC Committed Bytes 指标含义
GC Committed Bytes是.NET垃圾回收器(GC)已经向操作系统提交的内存总容量,包含三部分:
- 当前GC堆中被对象实际占用的内存
- GC为未来对象分配预留的空闲内存
- 因内存碎片化无法被回收并还给操作系统的闲置内存块
注意它和GC Heap Size的区别:后者仅统计堆中被对象实际占用的内存,前者是GC从操作系统拿到手的全部内存(不管是否被使用)。
二、你的输出异常分析
从你提供的dotnet-counters输出看:
GC Committed Bytes (MB)高达1269.08,但GC Heap Size (MB)仅19.337,两者差距极大GC Fragmentation (%)达到54.622%,属于严重碎片化
这说明GC虽然已经回收了无用对象,但因为堆内存碎片化严重,大量空闲内存块无法合并成连续的大块内存,导致GC无法将这些闲置内存还给操作系统,最终表现为已提交内存居高不下。
碎片化的常见诱因:
- 频繁分配大对象(你的
LOH Size (B)为8,032,824,大对象堆本身更难压缩) - 存在大量固定对象(
POH (Pinned Object Heap) Size (B)为3,765,072,固定对象会阻碍GC压缩内存) - 长期存活对象的频繁创建与释放,导致堆中残留大量无法合并的小空闲块
三、下一步排查与解决步骤
生成并分析内存转储
- 执行命令生成转储:
dotnet-dump collect -p <pid> - 用
dotnet-dump analyze加载转储,执行以下命令:dumpheap -stat:查看堆中对象的类型、数量、占用内存,定位占比高的对象dumpheap -mt <方法表地址>:针对可疑类型查看具体对象实例gcroot <对象地址>:检查对象的引用链,确认为何未被GC回收
- 执行命令生成转储:
启用GC日志排查碎片化根源
- 启动应用时添加环境变量:
export COMPlus_GCLogFile=gc.log export COMPlus_GCVerbose=1 - 运行应用一段时间后,查看
gc.log,重点关注:- 每次GC后的内存回收量、压缩情况
- 大对象堆(LOH)的回收日志,是否有压缩失败记录
- 启动应用时添加环境变量:
检查应用内存使用模式
- 排查大对象来源:是否有频繁创建大数组、超长字符串,或未及时释放的大对象缓存
- 检查固定对象场景:是否有非托管资源交互时频繁固定数组,或使用
GCHandle固定对象未释放 - 验证静态集合:是否有静态字典、列表等缓存对象未设置过期清理策略,导致对象长期存活
ASP.NET Core 专项检查
- 查看Session、分布式缓存配置:是否有大量未过期的数据堆积
- 检查中间件:是否有中间件持有请求上下文或其他对象的长期引用
- 排查第三方库:验证ORM框架、日志组件等是否存在内存泄漏问题
内容的提问来源于stack exchange,提问作者Igor Prischepa
相关产品推荐
相关产品推荐

