You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET5程序w3wp进程非托管内存泄漏,剩余内存去向查询

内存缺口的常见来源

  • GC堆预提交未使用内存
    .NET GC会以段为单位申请和提交内存,!eeheap输出的GC Heap Size仅统计了实际托管对象占用的内存,不包含已经提交但还未分配对象的段内存。你使用了16个GC堆(服务器GC模式),每个堆都会预申请一定量的提交内存,这部分差值通常是内存缺口的最大来源。
  • 未纳入统计的基础内存开销
    你之前的统计未包含以下已提交内存:
    • 线程栈:共234个线程栈,总大小386.375MB
    • 镜像加载:所有dll/exe的代码页、资源页提交,总大小170MB
    • 其他系统开销:TEB、PEB、系统缓存等,合计约2MB
      以上三项合计约558MB,已经占了缺口的近1/4。
  • 自定义内存分配器申请的内存
    若程序中引入了C/C++/Rust/Go等其他语言编写的模块,它们通常会使用自定义的内存分配器,直接通过VirtualAlloc申请大块内存,不会走Windows标准堆,因此!heap -s统计不到,这部分内存会被归类到!address的<unknown>分类中。
  • 内存映射文件
    程序直接创建的内存映射文件、系统加载的共享内存、大型文件缓存等,都会占用MEM_MAPPED类型的提交内存,不会被统计到托管或标准非托管堆中。
  • .NET其他运行时内存
    包括JIT生成的机器码缓存、异步IO缓冲区、Socket收发缓冲区、GC簿记内存、调试器代理内存等,都不会被计入GC堆或Loader堆统计。

排查步骤

  1. 先统计所有提交内存的分类总和,执行命令:
    !address -f:MEM_COMMIT -c:".echo %1 %3"
    导出所有提交内存块的类型和大小,计算<unknown>分类的总提交大小,即可定位缺口的核心分布。
  2. 排查GC堆实际提交总大小,执行命令:
    !eeheap -gc
    累加所有GC段的总大小,减去已分配对象的798MB,得到GC预提交未使用的内存大小。
  3. 排查大块未知内存的内容,找到!address中较大的<unknown>提交内存块,用db [内存地址]查看内容特征,判断是第三方库分配、内存映射文件还是其他运行时内存。

内容的提问来源于stack exchange,提问作者dotnetfly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 07:36:07