.NET Core 托管堆内存泄露/CPU异常的常见思路
常见的思路

- 内存泄露
托管内存暴涨大多数原因都是因为对象被GC Root(stack,gchandle,finalizequeue)持有,所以一直无法释放,所以观察的重点都在对象的可疑GC Root 上 - CPU高
CPU占用率高是由线程抬起来,因此观察线程当时在做什么,调用堆栈上的方法执行了多久是重点。大多数情况下,CPU高都是由于代码使用不当,导致Full GC,GC操作中标记-清除-压缩步骤又属于CPU密集型,高频次的GC无疑会大幅度提高CPU使用率。
观察哪个线程触发了FullGC,GC原因是什么是重点
- 程序卡死
程序卡死大多数出现在C/S中,重点观察主线程(UI线程)在干什么往往能快速定位问题。
B/S程序大概率是因为线程池耗尽,重点观察线程池队列,以及线程堆栈为什么消费慢。 - 程序崩溃
程序崩溃,往往是与非托管资源打交道的过程中发生了异常。此类问题很难定位,因为崩溃早已发生,只是你倒霉刚好戳破了而已。dump 只是一个快照,无法追踪曾经发生了什么事。
所以最好是能复现,使用Application Verifier等hook工具来找到第一现场。
如果无法复现,建议摇人。
此类场景如果前置知识储备不足,等自己能解决的时候,你问问你老板愿意等吗?
https://github.com/ctripxchuang/dotnetfly
常见的工具
Dump抓取
Procdump、Process Explorer和WinDbg都是Windows系统下常用的工具,它们在抓取进程转储(Dump)文件方面各有特点
Procdump
- 概述
Procdump是Sysinternals Suite工具集中的一个命令行实用程序,由微软开发。它主要用于在特定条件下自动捕获进程的内存转储文件,常用于分析应用程序崩溃、内存泄漏等问题。 - Dump抓取方式
- 基于CPU使用率触发:可以设置当进程的CPU使用率超过指定阈值并持续一定时间时,自动生成Dump文件。例如,以下命令表示当
notepad.exe进程的CPU使用率连续5秒超过50%时,生成Dump文件:
- 基于CPU使用率触发:可以设置当进程的CPU使用率超过指定阈值并持续一定时间时,自动生成Dump文件。例如,以下命令表示当
procdump -c 50 -s 5 notepad.exe
基于异常触发:可以指定当进程遇到特定异常(如未处理的异常)时生成Dump文件。例如,以下命令表示当calc.exe进程遇到未处理的异常时,生成Dump文件:
procdump -e 1 calc.exe
手动触发:直接指定进程名称或进程ID,手动生成Dump文件。例如,以下命令会立即为explorer.exe进程生成Dump文件:
procdump explorer.exe
- 特点
- 轻量级且易于使用,适合在生产环境中自动化抓取Dump文件。
- 支持多种触发条件,可灵活配置。

Process Explorer/任务管理器
- 概述
Process Explorer也是Sysinternals Suite中的一款工具,它是一个功能强大的进程管理和监控工具,提供了直观的图形化界面,可以实时查看系统中所有进程的详细信息,包括内存使用、线程、句柄等,同时也支持抓取进程的Dump文件。 - Dump抓取方式
- 在Process Explorer的进程列表中,找到需要抓取Dump文件的进程,右键单击该进程。
- 在弹出的菜单中,选择“Create Dump File”选项。
- 可以选择生成完整的Dump文件(Full Dump)或小型Dump文件(Mini Dump),然后指定Dump文件的保存路径。
- 特点
- 图形化界面操作,简单直观,适合不熟悉命令行的用户。
- 可以在查看进程详细信息的同时方便地抓取Dump文件。

WinDbg
- 概述
WinDbg是微软提供的一款强大的调试工具,可用于调试各种类型的应用程序,包括原生程序、托管程序和内核模式程序。它可以在调试过程中手动或自动抓取进程的Dump文件。 - Dump抓取方式<dump文件路径>
- 手动抓取:在WinDbg中附加到目标进程后,可以使用以下命令手动生成Dump文件:
.dump /ma <dump文件路径>
其中,/ma表示生成完整的Dump文件,<dump文件路径>是指定的Dump文件保存路径。
- 自动抓取:可以在WinDbg中设置断点或异常处理规则,当满足特定条件时自动生成Dump文件。例如,设置当进程遇到未处理的异常时生成Dump文件:
sxe ld:clr; g; .dump /ma <dump文件路径>
该命令表示当加载clr.dll时设置异常断点,继续执行程序,当遇到未处理的异常时生成完整的Dump文件。
- 特点
- 功能强大,支持对Dump文件进行深入分析和调试。
- 适合专业的开发人员和调试工程师处理复杂的问题。

省流版
首选Procdump,抓dump得靠自动化,手动抓可能时机不对了。
Dump分析
DotMemory、Visual Studio和WinDbg都是在软件开发过程中用于分析内存转储(Dump)文件的常用工具,它们各有特点和适用场景,以下为你详细介绍:
DotMemory
- 概述
DotMemory是JetBrains开发的一款专门用于.NET应用程序内存分析的工具。它提供了直观的图形化界面,使得开发者可以方便地对.NET程序的内存使用情况进行深入分析。 - 主要功能
- 实时内存分析:可以在应用程序运行时实时监控内存使用情况,显示对象的创建、销毁过程,帮助开发者及时发现内存泄漏和不合理的内存使用模式。
- 快照比较:支持对不同时间点的内存快照进行比较,清晰地展示哪些对象被创建、哪些被销毁以及对象数量和大小的变化,有助于定位内存增长的根源。
- 对象引用分析:能够分析对象之间的引用关系,通过引用图直观地展示对象的依赖关系,方便找出可能导致内存泄漏的引用链。
- 内存分配分析:可以跟踪对象的分配位置,找出哪些代码行创建了大量的对象,从而优化内存分配。
- 适用场景
适合.NET开发人员在开发和测试阶段对应用程序进行内存分析,快速定位和解决内存相关的问题,如内存泄漏、过度分配等。

Visual Studio
- 概述
Visual Studio是微软开发的一款集成开发环境(IDE),它不仅提供了强大的代码编辑、编译和调试功能,还内置了内存分析工具,可用于分析内存转储文件。 - 主要功能
- 集成式调试:可以在调试过程中直接查看应用程序的内存使用情况,设置断点,检查变量和对象的状态,方便进行实时调试和内存分析。
- 内存诊断工具:提供了内存诊断工具窗口,能够生成内存快照,分析对象的数量、大小和生命周期,支持对不同快照进行比较,找出内存变化的原因。
- 调用堆栈分析:结合调试信息,能够查看对象分配时的调用堆栈,帮助开发者定位内存分配的源头代码。
- 性能分析:可以与其他性能分析工具(如CPU使用率分析、线程分析等)结合使用,全面评估应用程序的性能。
- 适用场景
对于.NET和其他微软技术栈的开发人员来说,Visual Studio是一个一站式的开发和调试平台,在开发过程中可以方便地进行内存分析,无需额外安装其他工具。

WinDbg
- 概述
WinDbg是微软提供的一款强大的调试工具,可用于调试各种类型的应用程序,包括原生程序、托管程序和内核模式程序,也可以对内存转储文件进行深入分析。 - 主要功能
- 低级别调试:可以对程序进行底层调试,查看汇编代码、寄存器状态和内存布局,适用于分析复杂的内存问题和系统级故障。
- 脚本支持:支持使用脚本语言(如Python、JavaScript等)编写自定义调试脚本,扩展调试功能,实现自动化调试和分析。
- SOS扩展:对于.NET程序,WinDbg可以加载SOS(Son of Strike)扩展,提供丰富的.NET调试命令,如查看对象信息、调用栈、线程状态等,帮助分析.NET程序的内存问题。
- 跨平台调试:可以调试不同平台(如Windows、Linux等)上的应用程序,适用于跨平台开发和调试场景。
- 适用场景
适合专业的开发人员和调试工程师处理复杂的内存问题、系统级故障和跨平台调试场景,需要一定的调试经验和专业知识。
PerfView
见下一个段落,不再赘述。
省流版
简单来说,DotMemory适合观察内存分配,图形化界面,简单易用。
Visual Studio是简化版的windbg+图形化,
PerfView 对于对比两个dump的差异非常友好,
Windbg是万能的,文本界面,交互不友好,需要付出学习成本。
常见监控工具
PerfView
- 概述
PerfView 是由微软开发的一款免费、轻量级且功能强大的性能分析工具,主要用于对 .NET 应用程序以及 Windows 系统进行性能分析。它能够收集多种性能相关的数据,帮助开发者深入了解应用程序在运行时的行为,找出性能瓶颈。 - 主要功能
- 事件收集:可以收集大量的系统和应用程序事件,如 CPU 使用率、内存分配、垃圾回收、线程调度等。
- 数据可视化:将收集到的数据以直观的图表和表格形式展示,方便开发者分析。例如,通过火焰图可以清晰地看到 CPU 时间的分配情况。
- 问题诊断:帮助开发者诊断各种性能问题,如高 CPU 使用率、内存泄漏、线程阻塞等。
- 使用场景
在开发和调试 .NET 应用程序时,使用 PerfView 可以快速定位性能问题,优化应用程序的性能。例如,分析某个 Web 应用程序响应缓慢的原因,通过 PerfView 收集性能数据,找出耗时较长的操作。

https://ke.segmentfault.com/course/1650000041122988/section/1500000041123017
https://www.cnblogs.com/huangxincheng/category/2201783.html
.NET Core 托管堆内存泄露/CPU异常的常见思路的更多相关文章
- 关于 Unity 项目中的 Mono 堆内存泄露
关于 Unity 项目中的 Mono 堆内存泄露 题记:这是补一篇应该在将近一年前就应该写的记录,今天终于补上. 内存泄露是一个老话题了,之前我专门写过一篇 排查 Lua 虚拟机内存泄露 的文章,并且 ...
- JVM堆内存泄露分析
一.背景 公司有一个中间的系统A可以对接多个后端业务系统B,一个业务系统以一个Namespace代表, Namespace中包含多个FrameChannel(用holder保存),表示A连接到业务 ...
- Andorid 内存溢出与内存泄露,几种常见导致内存泄露的写法
内存泄露,大部分是因为程序的逻辑不严谨,但是又可以跑通顺,然后导致的,内存溢出不会报错,如果不看日志信息是并不知道有泄露的.但是如果一直泄露,然后最终导致的内存溢出,仍然会使程序挂掉.内存溢出大部分是 ...
- 深入研究EF Core AddDbContext 引起的内存泄露的原因
前两天逛园子,看到 @Jeffcky 发的这篇文章<EntityFramework Core依赖注入上下文方式不同造成内存泄漏了解一下>. 一开始只是粗略的扫了一遍没仔细看,只是觉得是多次 ...
- 堆内存腐败异常(STATUS_HEAP_CORRUPTION---0xC0000374)
什么是内存腐败 当堆内存位置的内容由于编程行为而被修改,超出了原始程序构造的意图时,计算机程序就会发生内存腐败,也可以叫内存破坏:这被称为违反内存安全.内存腐败的最可能原因是编程错误.当腐败的内存内容 ...
- .Net内存泄露原因及解决办法
.Net内存泄露原因及解决办法 1. 什么是.Net内存泄露 (1).NET 应用程序中的内存 您大概已经知道,.NET 应用程序中要使用多种类型的内存,包括:堆栈.非托管堆和托管堆.这里我们需 ...
- 转:.Net内存泄露原因及解决办法
1. 什么是.Net内存泄露 (1).NET 应用程序中的内存 您大概已经知道,.NET 应用程序中要使用多种类型的内存,包括:堆栈.非托管堆和托管堆.这里我们需要简单回顾一下. 以运行库为目标 ...
- 基于链表的C语言堆内存检测
说明 本文基于链表实现C语言堆内存的检测机制,可检测内存泄露.越界和重复释放等操作问题. 本文仅提供即视代码层面的检测机制,不考虑编译链接级的注入或钩子.此外,该机制暂未考虑并发保护. 相关性文章参见 ...
- 解决Net内存泄露原因
Net内存泄露原因及解决办法 https://blog.csdn.net/changtianshuiyue/article/details/52443821 什么是.Net内存泄露 (1).NET 应 ...
- JVM内存结构、参数调优和内存泄露分析
1. JVM内存区域和参数配置 1.1 JVM内存结构 Java堆(Heap) Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建.此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都 ...
随机推荐
- kali 安装 shodan
声明! 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无 ...
- 基于 MongoTemplate 实现MongoDB的复杂查询
MongoDB是典型的非关系型数据库,但是它的功能越来越复杂,很多项目中,我们为了快速拓展,甚至直接使用Mongo 来替代传统DB做数据持久化.虽然MongoDB在支持具体业务时没有问题,但是由于它是 ...
- win10下,更改程序磁贴图标
win8.1后,Windows支持程序图标的定制显示. 一般我们制作win程序时,会给程序设定一个标准的icon,不过这个图标不能满足win10的图标显示需求了,现在我们就用qq为例,定制一下程序图标 ...
- ServiceMesh 5:异常重试和超时保护提升服务可用性
★ ServiceMesh系列 1 背景 在复杂的互联网场景中,不可避免的会出现请求失败或者超时的情况. 从程序的的响应结果来看,一般是Response返回5xx状态的错误:从用户的角度去看,一般是请 ...
- uni-app生命周期小测
标签: js uni-app 前情 uni-app是我很喜欢的跨平台框架,它能开发小程序,H5,APP(安卓/iOS),对前端开发很友好,自带的IDE让开发体验也很棒,公司项目就是主推uni-app. ...
- 为了改一行代码,我花了10多天时间,让性能提升了40多倍---Pascal架构GPU在vllm下的模型推理优化
ChatGPT生成的文章摘要 这篇博客记录了作者在家中使用Pascal显卡运行大型模型时遇到的挑战和解决方案.随着本地大型模型性能的提升,作者选择使用vllm库进行推理.然而,作者遇到了多个技术难题, ...
- 使用nvm管理node版本,动态切换不同版本的node(解决安装报错)
使用nvm管理node版本,动态切换不同版本的node 1. 下载nvm安装包 下载地址,点这里进行下载 往下拉,选择 nvm-setup.zip 安装包 2. 安装nvm 注: 安装nvm之前,卸载 ...
- 【pygame】Python小游戏开发之看代码学编程
话说我学习的时候,英文文档难以理解,中文文档杂乱无章,最终还是觉得,还不如直接看代码学习. 下面是我学习过程中写的代码,注释写的很详细,我想会帮助你理解的 pip install pygame 1.游 ...
- oracle用命令执行sql脚本文件
当sql命令过多(sql文件过大)时,用plsql执行时比较慢而且容易超时,此时可以用sqlplus命令直接执行sql脚本文件,方法如下: 1.sqlplus登录 >sqlplus userna ...
- java double转string去除科学计数法"E" 非tostring()和valueOf()
在遇到需要将double类型转换string类型时,会出现转成科学计数法的形式,希望字符串能原样输出.直接使用会报java.lang.Double cannot be cast to java.lan ...