EtwR/EtwD内存占用过高求助:自研.NET 6程序致系统内存耗尽
内存耗尽排查建议(针对.NET 6程序在HP Z系列机型上的ETW池内存泄漏问题)
问题背景
自研.NET 6程序,核心执行TCP及SQL操作,在多款HP Z系列(Win10/Win11,16GB/32GB内存)机型上运行2-3天后,物理内存完全耗尽(开机仅占用6-7GB),分页内存占用超30-60GB;终止程序后内存需数小时才能恢复,无法即时释放。
已完成排查:
- RamMap显示Nonpaged Pool占9.3GB、Paged Pool占2.8GB,但与任务管理器统计值不符;任务管理器性能页显示Paged Pool达43.9GB、Nonpaged Pool达10.1GB
- Poolmon.exe排查发现
EtwD占用40GB分页池、EtwR占用9GB非分页池 - Tracelog/Logmon分析未发现ETW缓冲区大小异常,更新BIOS、驱动无效
排查步骤建议
1. 深入分析ETW会话状态
- 执行
logman query -ets列出所有活跃ETW会话,检查是否存在程序关联的自定义会话未正确关闭 - 针对
EtwD/EtwR对应的ETW提供者,用命令tracelog -start MyTrace -guid #<ProviderGUID> -f trace.etl -buffersize 1024 -max 10240捕获详细追踪日志,重点排查程序是否持续发送大量ETW事件却未被消费 - 用
xperf分析捕获的ETL日志,过滤EtwEventWrite相关事件,查看事件发送频率、单事件大小及是否存在未完成的会话
2. 排查程序的ETW使用逻辑
- 检查程序中是否直接使用
EventSource/EventCounter类,或第三方依赖(如SQL客户端、TCP框架)是否开启了高频率ETW日志 - 确认长生命周期对象中的
EventSource是否存在未释放的情况 - 临时禁用程序中所有自定义ETW日志,观察内存占用是否恢复,以此确认是否为程序触发的ETW泄漏
3. 验证系统ETW服务与配置
- 重启
Windows Event Log服务,观察池内存是否下降,排除服务自身异常 - 检查注册表路径
HKLM\SYSTEM\CurrentControlSet\Services\EventLog下的配置,确认ETW日志的最大容量、自动清理策略是否正常 - 查看系统事件日志(应用程序/系统日志),寻找ETW相关错误或警告(如缓冲区溢出、日志写入失败)
4. 排查HP机型定制软件/驱动
- 卸载HP预装管理软件(如HP Command Center、HP Support Assistant),部分厂商软件可能开启高频率ETW追踪
- 尝试将网络驱动替换为微软官方版本(而非HP定制驱动),排查TCP相关驱动的ETW日志泄漏
- 在
poolmon.exe中按P键排序池类型,再按B键按字节排序,结合findstr在驱动文件中查找EtwD/EtwR对应的池标签来源
5. 内存转储深度分析
- 内存占用异常时,用
procdump -ma <PID>捕获程序完整内存转储,同时用livekd或Windbg捕获系统内核转储 - 内核转储分析:
- 执行
!poolused 2查看池内存详细分配情况,定位EtwD/EtwR的分配调用栈 - 执行
!etw命令查看活跃ETW会话,检查是否存在缓冲区未回收的会话
- 执行
- 程序转储分析:查找是否存在大量未释放的
EventSource实例,或SQL/TCP操作中持续生成的未回收日志对象
6. 验证.NET运行时潜在问题
- 升级至.NET 6最新补丁版本,部分ETW相关内存泄漏问题可能已被修复
- 给程序添加环境变量
DOTNET_ETW_DISABLE=1,全局禁用.NET的ETW追踪,观察内存变化 - 检查异步TCP/SQL操作逻辑,异步场景下未正确处理ETW事件可能导致泄漏
内容的提问来源于stack exchange,提问作者David Harmon
相关产品推荐
相关产品推荐

