讲师中心 微信公众号
AI工具推荐 视频效率加速

C# 内存分析器使用方法 C# Visual Studio如何分析内存泄漏

浅辰君_1528

浅辰君_1528

发布时间:2026-01-29 10:11:02

|

929人浏览过

|

来源于php中文网

原创

在 Visual Studio 中按 Ctrl+Alt+F2 打开诊断工具,点击“内存使用率”下的“拍摄快照”按钮(需 Debug 配置、.NET Core 3.1+/5+),待疑似泄漏逻辑执行后再拍第二张对比;重点关注 Count Diff、Size Diff 和 Inclusive Size,右键类型查看引用链,警惕 Finalizer Queue 堆积和弱引用误判。

c# 内存分析器使用方法 c# visual studio如何分析内存泄漏

怎么在 Visual Studio 里快速启动内存分析器

Visual Studio 自带的诊断工具(Diagnostic Tools)和 .NET Memory Profiler 能直接捕获托管堆快照,不需要额外安装插件(VS 2019 及以后版本默认启用)。关键前提是项目必须以 Debug 配置运行,且目标框架为 .NET Core 3.1+ 或 .NET 5+(.NET Framework 仅支持部分功能,且需手动启用 GC 回收日志)。

操作路径:调试时按 Ctrl+Alt+F2 打开诊断工具窗口 → 点击“内存使用率”图表下方的“拍摄快照”按钮。注意:不要在程序刚启动时立刻拍,等疑似泄漏的逻辑执行完、对象理应被释放后,再拍第二张快照做对比。

  • 若看不到“内存使用率”选项,检查是否启用了“启用诊断工具”(工具 → 选项 → 调试 → 常规 → 启用诊断工具)
  • ASP.NET Core 项目需确保未启用 dotnet watch,否则快照可能失败并报错 Unable to collect memory data: process is not in a debuggable state
  • 控制台或 Windows Forms 应用需保持进程活跃(比如加个 Console.ReadLine()),否则调试器断开后无法采集

怎么看快照对比找出泄漏对象

两张快照之间,真正可疑的是“新分配但未释放”的对象——不是数量多的类,而是“增长量大 + 实例长期存活 + 类型明显不该常驻”的对象。比如 HttpClient 实例在 Web API 客户端里持续增长,或自定义的 EventHandler 持有窗体引用却没反注册。

在快照对比视图中,重点关注三列:Count Diff(实例数变化)、Size Diff(字节变化)、Inclusive Size(含子对象总大小)。右键某类型 → “查看对实例的引用”,可看到谁持有它(比如 static Dictionary<string object></string> 或未注销的 += 事件)。

  • 警惕 Finalizer Queue 里堆积的对象:说明 GC 已标记回收,但终结器线程卡住或未运行,常见于重写了 Finalize() 却没调用 GC.SuppressFinalize()
  • WeakReference 对象本身不阻止回收,但它的 Target 字段若非 null,就代表背后对象还活着——容易误判为“弱引用失效”,实则是强引用残留
  • 字符串(String)大量增长时,先查 StringBuilder.ToString() 是否被缓存,或日志组件是否把消息拼接后长期存进集合

为什么用 dotMemory 或 PerfView 补充分析

Visual Studio 内存分析器对大堆(>2GB)或高频率分配场景响应慢,且不支持导出完整对象图或跨进程追踪。这时候需要更底层的工具。

windows-screenshot-ocr
windows-screenshot-ocr

Windows全屏截图(自动标记鼠标位置)+ 原生OCR文字识别。本地运行,无需联网和API Key,适用于截图分析和自动化OCR场景。

下载

PerfView 是微软免费命令行工具,适合抓取 GC 行为:运行 PerfView /nogui /accepteula collect,复现操作后按 Ctrl+Shift+1 停止,打开 GCStats 视图看 % Time in GC 是否异常高(>10% 值得怀疑);再双击 HeapAllocStacks 查看哪些调用栈分配最多内存。

dotMemory(JetBrains)优势在于能标记“根路径”(Root Path)并高亮循环引用链,比如 A → B → C → A 这种 VS 默认不提示的隐式强引用。

  • 用 dotMemory 时务必勾选“Analyze memory traffic”,否则只看到静态快照,漏掉短生命周期对象的累积效应
  • PerfView 分析需开启 GC Heap Collect 事件(默认关闭),否则堆对象明细为空
  • 所有工具都依赖 Debug 构建,Release 下 JIT 优化可能导致内联或变量提前释放,让泄漏“消失”——这不是修复,是掩盖

常见误判和绕不开的坑

很多“疑似泄漏”其实是预期行为:比如 ThreadPool 线程长时间空闲会保活、String.Intern() 缓存永久驻留、AssemblyLoadContext 在 .NET Core 中默认不卸载。判断前先确认是否真违反设计契约。

  • Task 对象本身不泄漏,但未 await 的 Task 若内部持有了 CancellationTokenSource 或闭包变量,会导致后者无法回收
  • WPF 的 Binding 和 Command 默认强引用控件,用 RelativeSource 或静态资源时尤其要注意生命周期匹配
  • 第三方库(如 Entity Framework 的 DbContext)若被注入为 Singleton,其内部跟踪器会不断积累实体引用——这不是你的代码写错了,是 DI 生命周期配置错了

最麻烦的情况是:快照里找不到明显增长类型,但私有字节(Private Bytes)持续上涨。这时大概率是本机资源泄漏(SafeHandle 未释放、Marshal.AllocHGlobal 忘了 FreeHGlobal),得切到“本机堆”视图或用 Process Explorer 查句柄数。

热门AI工具

更多
超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6859

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1698

2024.03.01

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3488

2023.11.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1818

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2884

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6204

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

6049

2023.11.24

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Conan 2 安装指南
Conan 2 安装指南

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn