.NET 桌面软件内存泄露分析
WinDbg 分析
1. 托管还是非托管泄露
这是我们首先就要做出的抉择,可以使用 !address -summary & !eeheap -gc
来定位一下。
0:000> !address -summary--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free 1311 7ffc`e2b37000 ( 127.988 TB) 99.99%
<unknown> 4799 2`4f798000 ( 9.242 GB) 74.19% 0.01%
Heap 3029 0`906fe000 ( 2.257 GB) 18.12% 0.00%
Image 3435 0`2b530000 ( 693.188 MB) 5.43% 0.00%
Stack 226 0`11e00000 ( 286.000 MB) 2.24% 0.00%
Other 90 0`0025c000 ( 2.359 MB) 0.02% 0.00%
TEB 75 0`00096000 ( 600.000 kB) 0.00% 0.00%
PEB 1 0`00001000 ( 4.000 kB) 0.00% 0.00%--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_PRIVATE 7990 2`e6964000 ( 11.603 GB) 93.14% 0.01%
MEM_IMAGE 3445 0`2b536000 ( 693.211 MB) 5.43% 0.00%
MEM_MAPPED 220 0`0b61f000 ( 182.121 MB) 1.43% 0.00%--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE 1311 7ffc`e2b37000 ( 127.988 TB) 99.99%
MEM_COMMIT 8158 1`cf52a000 ( 7.239 GB) 58.11% 0.01%
MEM_RESERVE 3497 1`4df8f000 ( 5.218 GB) 41.89% 0.00%0:000> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x0000023ba303e940
generation 1 starts at 0x0000023ba2ebd0d0
generation 2 starts at 0x00000239a80f1000
ephemeral segment allocation context: none
...
Large object heap starts at 0x00000239b80f1000segment begin allocated size
00000239b80f0000 00000239b80f1000 00000239bfe174a8 0x7d264a8(131228840)
0000023a6f050000 0000023a6f051000 0000023a73780800 0x472f800(74643456)
Total Size: Size: 0xea9878f8 (3935860984) bytes.
------------------------------
GC Heap Size: Size: 0xea9878f8 (3935860984) bytes.
从中的 MEM_COMMIT
和 GC Heap Size
这两个指标来看,主要还是托管内存泄露,虽然非托管内存也不小,大概率还是托管这边导致的,有了这些信息之后,后面就是看下 托管堆
到底都是些什么对象。
0:000> !dumpheap -stat
Statistics:MT Count TotalSize Class Name
...
00007ffa2d7a1080 4923008 118152192 System.WeakReference
00007ffa2d725e70 2224022 125834760 System.Object[]
00007ffa2701de10 1044218 133659904 System.Windows.Documents.Paragraph
00007ffa2706b470 1045023 142123128 System.Windows.Documents.Run
00007ffa2706a9b0 2098480 151090560 System.Windows.Documents.TextTreeTextNode
00007ffa2d7267d0 1138661 159949302 System.Char[]
00007ffa2d7259c0 1231039 160962948 System.String
00007ffa29580cd8 214 165608376 MS.Internal.WeakEventTable+EventKey[]
00007ffa2d729750 2116556 169324480 System.Collections.Hashtable
00007ffa2d724478 2117718 209740224 System.Collections.Hashtable+bucket[]
00007ffa2706eb08 4175733 367464504 System.Windows.Documents.TextTreeTextElementNode
00007ffa2700ca48 2088016 384194944 System.Windows.ResourceDictionary
00007ffa2957fdc8 2344569 405666920 System.Windows.EffectiveValueEntry[]
从中的 TotalSize
来看并没有明显的特征,但从 Count
看还是有一些蛛丝马迹的,比如 System.Windows.Documents.TextTreeTextElementNode
对象为什么高达 417w
? 为什么 System.Windows.Documents.TextTreeTextNode
有 209w
? 虽然都是 WPF 框架的内部类,但从名字上看貌似和 文本类
控件有关系。
2. TextTreeTextElementNode 为什么没被回收
有了这些可疑信息,接下来就需要看下他们为什么没有被 GC 收掉?要想找到答案就需要抽几个 TextTreeTextElementNode
看下用户根是什么?可以使用 !dumpheap -mt xxx
找到 address 之后再用 !gcroot
观察一下。
0:000> !dumpheap -mt 00007ffa2706eb08Address MT Size
00000239a815f028 00007ffa2706eb08 88
00000239a815f080 00007ffa2706eb08 88
00000239a815f2e8 00007ffa2706eb08 88
00000239a815f340 00007ffa2706eb08 88
00000239a8259f18 00007ffa2706eb08 88
...0:000> !gcroot 0000023a637180e0!gcroot 0000023a637180e0
Thread e6c:000000aebe7fec20 00007ffa296c0298 System.Windows.Threading.Dispatcher.GetMessage(System.Windows.Interop.MSG ByRef, IntPtr, Int32, Int32)rsi: -> 00000239a8101688 System.Windows.Threading.Dispatcher-> 0000023b4630e9a8 System.EventHandler-> 0000023b4630a990 System.Object[]-> 00000239a8425648 System.EventHandler
大多是 TextTreeTextElementNode 和 TextTreeFixupNode 之间的交叉引用,还得耐点心慢慢往上翻,看看可有什么蛛丝马迹,经过仔细排查,发现有一个 RickTextBox
控件
从源码看,在项目中实现了一个自定义的 RichTextBox
控件来实现日志记录,内存泄露问题应该就在这里。
.NET 桌面软件内存泄露分析相关推荐
- java内存泄露分析方案
java内存泄露分析方案 - 准备工作 1.工具:Memory Analyzer Tool (mat); 1)安装Memory Analyzer Tool (mat) 2.原料:dump.hprof ...
- 一次.net托管内存泄露分析
简介:一次.net托管内存泄露分析 最近协助分析了一个.net进程内存泄露的问题,过程分享给大家. 症状:客户的服务端.net进程出现分钟级的cpu抖动,接近100%后落回. 图1 分析:支持同学通过 ...
- 如何使用MAT进行JVM内存泄露分析
转载自 如何使用MAT进行JVM内存泄露分析 在<Java Agent的隔离实现以及卸载时一些坑>中,卸载Agent之后,使用 jmap-histo:live pid命令验证执行FGC, ...
- 记一次 JAVA 的内存泄露分析
记一次 JAVA 的内存泄露分析 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.com/jasonGeng88/blog 当前环境 jdk == 1.8 httpasyn ...
- JAVA内存泄露分析和解决方案及WINDOWS自带查看工具
JAVA内存泄露分析和解决方案及WINDOWS自带查看工具 Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最 ...
- JVM内存管理概述与android内存泄露分析
一.内存划分 将内存划分为六大部分,分别是PC寄存器.JAVA虚拟机栈.JAVA堆.方法区.运行时常量池以及本地方法栈. 1.PC寄存器(线程独有):全称是程序计数寄存器,它记载着每一个线程当前运行的 ...
- 内存泄露分析之MAT工具使用
转载请注明地址:http://blog.csdn.net/yincheng886337/article/details/50524890 MAT工具使用 理解相关概念 在了解MAT工具之前,我们需先对 ...
- Android 内存泄露分析
1 内存泄漏简介 内存泄漏是指内存空间使用完毕后无法被释放的现象.尽管Java有垃圾回收机制(GC),但是对于还保持着引用,逻辑上却已经不会再用到的对象,垃圾回收器不会回收它们. 内存泄漏带来的危害: ...
- 一个Vue页面的内存泄露分析
什么是内存泄露?内存泄露是指new了一块内存,但无法被释放或者被垃圾回收.new了一个对象之后,它申请占用了一块堆内存,当把这个对象指针置为null时或者离开作用域导致被销毁,那么这块内存没有人引用它 ...
最新文章
- 为何艾伦·图灵想让AI智能体故意犯错
- lodash 工具库
- SD-WAN的四大错误观念
- 手机投电脑_这七个电脑软件,用过的才知道多好用!
- Lucene工具箱之OpenBitSet(一)
- mysql 导出gbk_mysqldump指定编码导出数据,GBK编码实践
- Machine Schedule
- 小余学调度:调度禁忌操作讲解(持续更新中ing)
- 转发2篇大学生写的博文---看了比较有感触
- 美国和中国将成数据中心建设首选之地
- jeecg 与 jeecg-p3有什么区别?
- cahrt框架 ios_iOS - Charts(一) - BarChartView
- html 判断当前窗口是否是子窗口,JavaScript window.open 判断子窗口是否已经存在
- 开发人员常用的Oracle导入/导出命令
- 使用 CloudFlare CDN 自定义节点加速网站
- itextpdf 合并单元格 横向纵向
- windows开机自启exe程序bat
- 通过调用接口查询ISBN的图书信息
- Excel行高与像素值,列宽与像素值之间的转换,绘制Excel像素画。
- ZUCC_离散数学基础__简单期末复习整理