C#性能优化基础:内存诊断(dump)

news/2025/10/9 18:46:42/文章来源:https://www.cnblogs.com/shanfeng1000/p/19077259

  接上一篇:C#性能优化基础:垃圾回收机制

  本文说下怎么去查找内存问题,举个例子,我们有这样的一段程序:

    namespace ConsoleApp1{internal class Program{static List<Demo> Demos { get; } = new List<Demo>();static void Main(string[] args){while (true){Console.Write($"请输入要创建的对象个数(已有对象{Demos.Count}个):");var line = Console.ReadLine();if (int.TryParse(line, out var count)){while (count-- > 0){Demos.Add(new Demo() { Value7 = new Demo[] { new Demo() } });}}else{break;}}}}internal class Demo{public string Value1 { get; set; } = Guid.NewGuid().ToString("N");public string Value2 { get; set; } = Guid.NewGuid().ToString("N").PadRight(100000, '-');public int Value3 { get; set; } = new Random().Next(1, 100);public DateTime Value4 { get; set; } = DateTime.Now;public bool? Value5 { get; set; } = new Random().Next(0, 2) == 1;public DayOfWeek Value6 { get; set; } = (DayOfWeek)(new Random().Next(0, 7));public Demo[] Value7 { get; set; }}}

  代码很简单就不说了,我们在linux下去运行这段代码,为什么是linux呢,因为windows的下方法是差不多的,linux命令更方便展示些。

  首先,我们需要安装dotnet,我这边用的.net6,安装在/opt/dotnet目录,更多版本可以去官网下载sdk:https://dotnet.microsoft.com/en-us/download

  接着我们需要配置dotnet的安装目录:

    # 需要在/etc/dotnet/install_location中配置sudo mkdir /etc/dotnetecho /opt/dotnet > /etc/dotnet/install_location

  如果不配置,后续可能会出现下面的异常:

  image

  然后去官网下载我们需要的工具:

  下载dotnet-counters :https://learn.microsoft.com/zh-cn/dotnet/core/diagnostics/dotnet-counters

  下载dotnet-dump:https://learn.microsoft.com/zh-cn/dotnet/core/diagnostics/dotnet-dump

  我们可以直接下载linux下的可执行文件,把它放到dotnet的安装目录即可。

  然后我们把项目运行起来,通过dotnet-counters命令可以查看当前服务器上运行dotnet程序:sudo ./dotnet-counters ps

  image

  我这里采用run命令运行项目的,这样我们就拿到了前面的进程ID(那个demo的项目名)。

  image

  注:有人可能会想,如果只为了拿进程ID,我们可以同topps命令都可以,确实是的,但是那样拿到的命令不一定有用,因为它要求我们的dotnet程序和dotnet-counters在同一个域,比如程序运行在服务单元,但是dotnet-counters运行在shell,那么可能获取不到程序的信息,即上面的命令输出可能没有dotnet进程的信息。

  然后我们还可以通过dotnet-counters命令查看程序进程内部的内存变化:sudo dotnet-counters monitor --refresh-interval=1 -p 361706,结果大概如下图:

  image

  我们关注几个指标就好了:

    GC Heap Size (MB) :堆内存大小Gen X GC Count (Count / 1 sec):第X代垃圾数量Gen 0 Size (B):第X代垃圾大小LOH Size (B):大对象堆的大小

  接下来我们可以通过dotnet-dump来生成转储文件来查看内存中的数据了(转储文件可以理解为此刻内存的一个快照,把它收集到文件里面方便查看):

    # 生成转储文件sudo ./dotnet-dump collect -p 361706# 分析转储文件,core_20250906_175409是上面生成的转储文件sudo ./dotnet-dump analyze core_20250906_175409

  image

  分析查看命令常用的有下面这些(更多命令可以参考官网:https://learn.microsoft.com/en-us/dotnet/framework/tools/sos-dll-sos-debugging-extension)

    dumpheap:过滤、统计、打印内存数据信息-stat:统计内存数据,一般按照方法表展示(方法表可以理解为就是类型,一个类型的所有数据放在一起就是方法表)-mt:指定要展示的方法表-min:内存的最小值-max:内存的最大值-type:指定包含的类型,建议类型的完整形式,包括明明空间,如:System.String-live:只列出还活动的内存数据-strings:统计字符串数据的信息-short:将输出限制为只是每个对象的地址dumpobj:显示有关指定地址处的对象的信息。 DumpObj 命令显示对象的字段、EEClass 结构信息、方法表和大小。可简写成do-nofields:可阻止显示对象的字段,它对 String 这样的对象很有用。dumparray:检查数组对象的元素,可简写成da-start:选项指定开始显示元素的起始索引。-length:选项指定要显示的元素数量。-details:选项使用 dumpobj 和 dumpvc 格式显示元素的详细信息。-nofields:选项可阻止显示数组。 此选项仅在指定 -details 选项后可用。dumpvc:显示有关指定地址处的值类字段的信息。dc:查看字符串数据,对于大字符串比较有效gcroot:显示有关对指定地址处的对象的引用(或根)的信息

  接下来逐个展示一下他们的用法:

    # 统计每个方法表的对象个数和总内存dumpheap -stat# 统计每个方法表还活动的大对象的个数和总内存dumpheap -stat -min 85000 -live# 统计大字符串的个数和内存大小dumpheap -strings -min 85000# 查看某个方法表的数据dumpheap -mt 7f0af83bd2e0# 查看某个方法表的大对象数据dumpheap -mt 7f0af83bd2e0 -min 85000 -live# 查看某个类型的数据dumpheap -type System.String

  比如我们查看包含Demo类型的数据:dumpheap -type Demo

  image

  上图说我们Demo类有三个地方:List<Demo>(1个)、Demo[](3个)、Demo对象(2个),它们的地址也在上面列出来了

  我们现在逐个来对应他们的关系,最外层肯定是List<Demo>数组对象,所以我们可以查看一下链表数据(因为链表属于对象,所以用do查看):do 7f72c8008dd0

  image

  可以看到List<Demo>数组对象里面有三个字段,里面的_item字段记录的就是一个Demo[]数组对象(地址7f72c805eb30),这也解释了为什么会有三个数组对象的原因。

  我们接着去看_item字段里面是什么(因为是数组,所以用dumparray):dumparray 00007f72c805eb30

  image

  可以看到这个数组有四个元素,但是只有第一个有数据,其他都是null,我们明明至添加了一个,为什么有四个?读者可自行思考下。

  我们接着看第一个元素里面是什么(数组里面是Demo对象,所以用do查看):do 00007f72c8014ac8

  image

  可以看到对象里面的所有字段,我们可以逐个检查:

  Value3是int数值类型,值是78,Value6是美剧类型,值是4,都已经打印出来了。

  Value1Value2是字符串,可以通过do查看:

  image

  可以看到Value2的结果没有打印出来,因为结果太长了,我们可以换个方式打印,通过dc命令,通过上图得到Value2的长度是100000,那么我们执行:dc -c 100100 -w 100100 00007f72d7fff038 ,这样我们就把所有的字符串都打印出来了。

  Value4DateTime结构体,但是内存里面是一个地址,所以我们不能用do,应该用dumpvc 去查看:dumpvc 00007f72fe0c8668 00007f72c8014af0

  image

  可以看到它只有一个_dateDatalong类型数据,它其实就是DateTimeTick属性。

  Value5Nullable,它是机构体,所以应该通过dumpvc查看:dumpvc 00007f72fe0c8950 00007f72c8014af8

  image

  Value7是数组,我们可以用dumparray查看,这就回到上面的情况了,这里就不解释了

  最后,gcroot也可以演示一下,比如对于Value7,我们执行: gcroot 00007f72c805e948

  image

  它告诉我们地址是怎么关联引用的。

  

  总结

  本文只是介绍怎么去处理内存问题,如果碰到内存过高或者没有释放,我们可以通过dump去查原因。

  当然我们可以通过VS去分析,但是如果是开发环境还好,如果是生产环境,转储文件一般比较大,因为本来就是要处理内存大的原因,而转储文件就是内存的快照,自然就大了,文件一大就不方便搬运。。。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/933782.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年企业级LLM内容安全防护指南:鉴冰AI FENCE流式网关技术深度解析

2025年企业级LLM内容安全防护指南:鉴冰AI FENCE流式网关技术深度解析随着生成式AI在企业关键业务中的深度应用,LLM输出违规内容防护已从技术选项升级为合规刚需。AI-FOCUS团队推出的鉴冰AI FENCE(AI安全围栏)采用流…

完整教程:FPGA学习笔记——图像处理之亮度调节(Gamma)

完整教程:FPGA学习笔记——图像处理之亮度调节(Gamma)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas…

Kubernetes Ingress:管理集群外部访问的入口网关

在k8s之服务Service章节,我们详细的介绍了Service的组成以及相关的原理。Service可以将自身的服务暴露出去,给集群内部服务或者给外部服务去使用,或者将外部服务分装为一个service,供给集群内部服务使用。而今天介…

搜索选讲

前言 我太菜了,如有没写清楚的地方大家轻喷. 爆搜 P4467 k短路 Hint:沿用次短路的思路(P1491). 不能经过重复的点是一个很强的限制,直接搜无论怎么剪枝都会被卡爆. 由于没有负权边,最短路必然不会经过重复的点,…

深入解析:在Linux中部署tomcat

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

vue打包的项目,从根目录进去路由可访问,浏览器直接打开这个路由不可访问

Vue 项目路由访问问题分析 您描述的问题是 Vue 打包后的项目在直接访问子路由时出现 404 错误,而从首页导航可以正常访问。这是一个常见的 Vue 路由配置问题。 问题原因 这是因为您使用的是 Vue Router 的 history 模…

深入解析:Docker容器化部署简要指南

深入解析:Docker容器化部署简要指南2025-10-09 18:29 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !im…

IObit Uninstaller一款强大的卸载工具!IObit Uninstaller卸载工具,IObit Uninstaller下载安装教程

软件介绍 IObit Uninstaller 是一款强大且实用的卸载工具。它能有效替代 Windows 自带卸载功能,,不残留相关文件与注册表信息,防止因残留导致系统变慢或出错。软件支持多种卸载方式,常规卸载适用于大多数程序;批量…

网络配置不再难:4G/Wi-Fi/以太网/虚拟网卡全指南

多种网络接口并存的时代,掌握4G、Wi-Fi、以太网和虚拟网卡的配置是必备技能。本文系统讲解各类连接方式的设置方法,助你轻松应对复杂网络场景。 网络适配器,它的一个更广为人知的名字是——网卡。 在应用开发中我们…

2025开关按钮厂家最新推荐榜:开关按钮,带灯开关按钮,防水开关按钮,防爆开关按钮,防腐开关按钮等全种类覆盖,高品质设计与卓越性能口碑之选

在当今科技飞速发展的时代,开关按钮作为各种电子设备、电气系统中不可或缺的基础元件,其重要性不言而喻。无论是工业自动化生产线上的精密控制设备,还是日常生活中的家用电器,开关按钮都在默默地发挥着关键作用。随…

一种排查java.lang.OutOfMemoryError: Metaspace的方法

有现场反应k8s中的java应用出现java.lang.OutOfMemoryError: Metaspace,但是没有提供hprof转储文件,所以本地排查该问题。 Metaspace区域的内存溢出错误,通常意味着 JVM 中加载的类元数据超出了限制。 jstat -class…

MDX Blog Post

Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/).:::tipUse the power of React to create interactive blog posts....Blog …

Long Blog Post

This is the summary of a very long blog post,Use a `` comment to limit blog post size in the list view.This is the summary of a very long blog post,Use a `` comment to limit blog post size in the list …

First Blog Post

Lorem ipsum dolor sit amet...Lorem ipsum dolor sit amet......consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolo…

本站点即将在2025年改变研究方向和目标

由于当前部分社区发展已经朝向不可控领域,以及流浪的猎人计划做一些其他的东西,预计会在今年内开始对该站点的研究方向进行一些改变。 我们会在未来降低一些特定技术研究的公开,如果一些东西最后公开出来变成了“外…

详细介绍:内置高压MOS的智能调光方案:AP5126 LED降压恒流驱动芯片

详细介绍:内置高压MOS的智能调光方案:AP5126 LED降压恒流驱动芯片pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &quo…

实用指南:12_OkHttp初体验

实用指南:12_OkHttp初体验pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", …

深入解析:llm的ReAct

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

(AE)Adobe After Effects 2025 视频后期制作软件!安装包永久免费免激H解锁版下载与图文详细安装教程!!

软件介绍 Adobe After Effects 2025 作为一款专业的动态图形与视觉特效软件,在影视后期制作领域地位显著。它提供了丰富且强大的功能,能助力创作者将创意变为现实。它支持2D及3D动画,透过图层控制音频与视频合成效果…

Postgresql主从配置

主从机器先安装Postgresql 安装postgresql: postgresql 最新版 sudo sh -c echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list wg…