记一次 .NET某培训学校系统 内存碎片化分析

news2025/1/17 8:56:22

一:背景

1. 讲故事

前些天有位朋友微信上找到我,说他们学校的Web系统内存一直下不去,让我看下到底是怎么回事,老规矩让朋友生成一个dump文件丢给我,看一下便知。

二:WinDbg 分析

1. 托管还是非托管

要想看托管还是非托管,可以用 !address -summary 观察下内存段。


0:000> !address -summary

--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free                                    384     7dbe`3d662000 ( 125.743 TB)           98.24%
<unknown>                              9653      241`9e9fd000 (   2.256 TB)  99.98%    1.76%
Stack                                   153        0`125d0000 ( 293.812 MB)   0.01%    0.00%
Image                                  1912        0`0b0f2000 ( 176.945 MB)   0.01%    0.00%
Heap                                    110        0`0669a000 ( 102.602 MB)   0.00%    0.00%
Other                                    12        0`001ce000 (   1.805 MB)   0.00%    0.00%
TEB                                      51        0`00066000 ( 408.000 kB)   0.00%    0.00%
PEB                                       1        0`00001000 (   4.000 kB)   0.00%    0.00%

--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE                                384     7dbe`3d662000 ( 125.743 TB)           98.24%
MEM_RESERVE                            2794      23f`666dd000 (   2.248 TB)  99.59%    1.76%
MEM_COMMIT                             9098        2`5c2b1000 (   9.440 GB)   0.41%    0.01%

从卦中信息的 MEM_COMMITHeap 来看,应该就是托管内存的问题了。

2. 托管堆排查

要查看托管堆,可以用 !eeheap -gc 观察下。


0:000> !eeheap -gc

========================================
Number of GC Heaps: 8
----------------------------------------
Heap 0 (00000273748727a0)
Small object heap
         segment            begin        allocated        committed allocated size       committed size      
generation 0:
    02b388ff24f0     027615400020     0276157f76f8     027615800000 0x3f76d8 (4159192)   0x400000 (4194304)  
...
generation 1:
    02b388ff5e00     02762a000020     02762a01e460     02762a0b0000 0x1e440 (123968)     0xb0000 (720896)    
generation 2:
    02b388f81840     027385000020     0273853a2b20     027385400000 0x3a2b00 (3812096)   0x400000 (4194304)  
    02b388f818f0     027385400020     0273857ee220     027385800000 0x3ee200 (4121088)   0x400000 (4194304)  
    02b388f81e70     027387400020     0273877914e8     0273877b2000 0x3914c8 (3740872)   0x3b2000 (3874816)  
    02b388f823f0     027389400020     0273897bf580     0273897df000 0x3bf560 (3929440)   0x3df000 (4059136)  
    02b388f82600     02738a000020     02738a3644e0     02738a368000 0x3644c0 (3556544)   0x368000 (3571712)  
    ...
    02b388f85fc0     02739f000020     02739f253e10     02739f257000 0x253df0 (2440688)   0x257000 (2453504)  
    02b388f861d0     02739fc00020     02739fffc9f0     02739ffff000 0x3fc9d0 (4180432)   0x3ff000 (4190208)  
    02b388f86490     0273a0c00020     0273a0f829c0     0273a0fbd000 0x3829a0 (3680672)   0x3bd000 (3919872)  
    02b388f87040     0273a5000020     0273a5332f78     0273a5337000 0x332f58 (3354456)   0x337000 (3371008)  
    02b388f875c0     0273a7000020     0273a72e4710     0273a7305000 0x2e46f0 (3032816)   0x305000 (3166208) 
    ...
Large object heap
         segment            begin        allocated        committed allocated size       committed size      
    02b388f84f40     027399000020     02739908f520     027399090000 0x8f500 (587008)     0x90000 (589824)    
Pinned object heap
         segment            begin        allocated        committed allocated size       committed size      
    02b388f812c0     027383000020     02738300b080     027383011000 0xb060 (45152)       0x11000 (69632)     
------------------------------
GC Allocated Heap Size:    Size: 0x2212923b0 (9146278832) bytes.
GC Committed Heap Size:    Size: 0x23b676000 (9586565120) bytes.

从卦中看当前的托管内存是 9.5G,通过观察内存都是被 Gen2 给吃掉了,那 Gen2 上都是什么对象呢?我们用 !dumheap -stat 观察下。


0:000> !dumpheap -stat
Statistics:
          MT     Count     TotalSize Class Name
...
7ff954ecd918    91,030     9,467,120 System.Reflection.RuntimeMethodInfo
7ff95701c8f0   572,034    18,305,088 System.Globalization.DateTimeFormatInfo+TokenHashValue
7ff954c9fd00 1,010,024    62,198,216 System.String
7ff95502fc10    62,645   173,045,678 System.Byte[]
0273747f9610    28,313 8,761,969,520 Free
Total 3,305,047 objects, 9,143,856,580 bytes

不看卦不知道,一看吓一跳,9G的内存,Free 就吃掉了 8.7G,看样子又是经典的 内存碎片化 了,赶紧到 Gen2 上去看一看狼狈现场。


0:000> !dumpheap 02739fc00020 02739fffc9f0
         Address               MT           Size
    02739fc00020     0273747f9610        717,136 Free
    02739fcaf170     7ff95502fc10          8,216 
    02739fcb1188     7ff955478798             64 
    02739fcb11c8     0273747f9610        607,864 Free
    02739fd45840     7ff95502fc10          8,216 
    02739fd47858     7ff955478798             64 
    02739fd47898     0273747f9610      2,205,336 Free
    02739ff61f30     7ff95502fc10          8,216 
    02739ff63f48     7ff955478798             64 
    02739ff63f88     0273747f9610         99,736 Free
    02739ff7c520     7ff95502fc10          8,216 
    02739ff7e538     7ff955478798             64 
    02739ff7e578     0273747f9610         76,504 Free
    02739ff91050     7ff95502fc10          8,216 
    02739ff93068     7ff955478798             64 
    02739ff930a8     0273747f9610        355,728 Free
    02739ffe9e38     7ff95502fc10          8,216 
    02739ffebe50     7ff955478798             64 
    02739ffebe90     0273747f9610         60,168 Free
    02739fffa998     7ff95502fc10          8,216 
    02739fffc9b0     7ff955478798             64 

Statistics:
          MT Count TotalSize Class Name
7ff955478798     7       448 System.IO.FileSystemWatcher+AsyncReadState
7ff95502fc10     7    57,512 System.Byte[]
0273747f9610     7 4,122,472 Free
Total 21 objects, 4,180,432 bytes
...

卦中信息是明显的 内存碎片化 现象,可以看到每一个 Free 后面都跟着一个 8216,那这玩意是干嘛的,为什么它不会 GC 回收呢?

3. 碎片化排查

要想找到不会回收的原因,我们用 !gcroot 看一下。


0:000> !gcroot 02739fffa998
Caching GC roots, this may take a while.
Subsequent runs of this command will be faster.

HandleTable:
    0000027374723fc0 (async pinned handle)
          -> 02739dc758c8     System.Threading.OverlappedData 
          -> 02739fffa998     System.Byte[] 

从卦中可以看到它是被 System.Threading.OverlappedData 持有,熟悉异步编程的朋友应该都知道IO完成端口,C# 中的 OverlappedData 还会绑定 handlebyte[]IOThread 等信息,我们挖一下其中的 _userState


0:000> !do 02739dc758c8
Name:        System.Threading.OverlappedData
Fields:
              MT    Field   Offset                 Type VT     Attr            Value Name
00007ff95502bce0  4000b00        8  System.IAsyncResult  0 instance 0000000000000000 _asyncResult
00007ff954af93b0  4000b01       10        System.Object  0 instance 000002739dc75910 _callback
00007ff95547f208  4000b02       18 ...eading.Overlapped  0 instance 000002739dc75880 _overlapped
00007ff954af93b0  4000b03       20        System.Object  0 instance 000002739fffa998 _userObject
00007ff954c9ac30  4000b04       28                  PTR  0 instance 000002b41023f130 _pNativeOverlapped
00007ff954c99250  4000b05       30        System.IntPtr  1 instance 0000000000000000 _eventHandle
00007ff954c1e8c0  4000b06       38         System.Int32  1 instance                0 _offsetLow
00007ff954c1e8c0  4000b07       3c         System.Int32  1 instance                0 _offsetHigh

0:000> !do 000002739dc75880
Name:        System.Threading.ThreadPoolBoundHandleOverlapped
Fields:
              MT    Field   Offset                 Type VT     Attr            Value Name
00007ff95547f558  4000b08        8 ...ng.OverlappedData  0 instance 000002739dc758c8 _overlappedData
00007ff955478d48  4000d2f       10 ...ompletionCallback  0 instance 00000273869e27a8 _userCallback
00007ff954af93b0  4000d30       18        System.Object  0 instance 000002739fffc9b0 _userState
00007ff9554791a8  4000d31       20 ...locatedOverlapped  0 instance 000002739dc75860 _preAllocated
00007ff954c9ac30  4000d32       30                  PTR  0 instance 000002b41023f130 _nativeOverlapped
00007ff955479790  4000d33       28 ...adPoolBoundHandle  0 instance 0000000000000000 _boundHandle
00007ff954c1b3c0  4000d34       38       System.Boolean  1 instance                0 _completed
00007ff955478d48  4000d2e      930 ...ompletionCallback  0   static 00000273869e2898 s_completionCallback

0:000> !do 000002739fffc9b0 
Name:        System.IO.FileSystemWatcher+AsyncReadState
Fields:
              MT    Field   Offset                 Type VT     Attr            Value Name
00007ff954c1e8c0  400002b       30         System.Int32  1 instance                1 <Session>k__BackingField
00007ff95502fc10  400002c        8        System.Byte[]  0 instance 000002739fffa998 <Buffer>k__BackingField
00007ff955026688  400002d       10 ...es.SafeFileHandle  0 instance 000002739dc757d8 <DirectoryHandle>k__BackingField
00007ff955479790  400002e       18 ...adPoolBoundHandle  0 instance 000002739dc75828 <ThreadPoolBinding>k__BackingField
00007ff9554791a8  400002f       20 ...locatedOverlapped  0 instance 000002739dc75860 <PreAllocatedOverlapped>k__BackingField
00007ff955479248  4000030       28 ...eSystem.Watcher]]  0 instance 000002739dc75848 <WeakWatcher>k__BackingField

从卦中可以看到原来是 FileSystemWatcher 在作祟,说实话看到这个东西我马上就有条件反射,肯定又是经典的 ReloadOnChange=true 导致的,果然直觉就是对的,一搜代码果然有,截图如下:

三:总结

说实话 ReloadOnChange=true 真的是万恶之源,据往期分析可列出如下四大罪证:

  • 文件句柄暴涨
  • byte[]导致的内存暴涨
  • pinned 导致的内存碎片化
  • 线程池暴涨 导致的程序无响应

大家使用前需 慎之又慎,三思而后行!!!

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

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

相关文章

elasticsearch 配置用户名和密码

无密码的其他配置项在&#xff1a;https://blog.csdn.net/Xeon_CC/article/details/132064295 elasticsearch.yml配置文件&#xff1a; xpack.security.enabled: true xpack.security.http.ssl.enabled: true xpack.security.http.ssl.keystore.path: /path/to/elastic-certi…

js实现左右列表对齐(左边点击时,右边滚动和左边对齐。反之右边点击时,左边滚动和右边对齐)

需求&#xff1a; js实现左右列表对其&#xff08;左边点击时&#xff0c;右边滚动和左边对齐。反之右边点击时&#xff0c;左边滚动和右边对齐&#xff09; 效果示意图&#xff1a; 点击6666的效果图如下&#xff1a; 实现代码&#xff1a; 思路&#xff1a; 1…需要一个…

日期类相关练习题

前言 本文记录一些有关日期类的oj题题解,实现过日期类小项目的可以练一下手,本文不做过多讲解. 目录 前言一、求123...n题目介绍:解题思路:代码实现: 二、计算日期到天数转换题目介绍:解题思路:代码实现: 三、日期累加题目介绍:解题思路:代码实现 四、日期差值题目介绍代码实…

W6100-EVB-PICO做DNS Client进行域名解析

前言 在上一章节中我们用W6100-EVB-PICO通过dhcp获取ip地址&#xff08;网关&#xff0c;子网掩码&#xff0c;dns服务器&#xff09;等信息&#xff0c;给我们的开发板配置网络信息&#xff0c;成功的接入网络中&#xff0c;那么本章将教大家如何让我们的开发板进行DNS域名解…

四、JVM-对象内存模型

Java对象内存模型 一个Java对象在内存中包括3个部分&#xff1a;对象头、实例数据和对齐填充 数据 内存 – CPU 寄存器 -127 补码 10000001 - 11111111 32位的处理器 一次能够去处理32个二进制位 4字节的数据 64位操作系统 8字节 2的64次方的寻址空间 指针压缩技术 JDK1.6出…

聚观早报 | iPhone 15 Pro系列有望成为苹果三年来最大升级

【聚观365】8月3日消息 苹果三年来最大升级 小米驰援北京河北暴雨救灾 印度要求特斯拉仿效苹果 比亚迪7月新能源车销量同比增长61% 富士康计划在印度新建两家零件工厂 苹果三年来最大升级 苹果将继续在今年9月举办一年一度的秋季新品发布会&#xff0c;届时全新的iPhone …

GC 深入(小白,对gc有一个进一步的了解)

垃圾回收器的搭配 一般固定 一般这年轻代垃圾回收器&#xff0c;老年代垃圾回收器&#xff0c;如上图搭配着使用 1.8呢默认就是最后边那哥俩 jvm调优 一个就是增加吞吐量 一个就是减少STW的时间。 三色标记算法&#xff08;理解根可达算法&#xff09; 并发的可达性分析 有…

8.2Jmeter5.1:察看结果树的响应结果乱码

【问题描述】 Jmeter察看结果树的响应结果乱码 原因&#xff1a;jmeter.properties未设置语言 【解决方案】 修改jmeter.properties的属性&#xff0c;然后重启Jmeter # The encoding to be used if none is provided (default ISO-8859-1) sampleresult.default.encodingut…

AB实验遇到用户不均匀怎么办?—— vivo游戏中心业务实践经验分享

作者&#xff1a;vivo 互联网数据分析团队 - Li Bingchao AB实验是业务不断迭代、更新时最高效的验证方法之一&#xff1b;但在进行AB实验效果评估时需要特别关注“用户不均匀”的问题&#xff0c;稍不注意&#xff0c;产出的研究结论就可能谬以千里&#xff0c;给业务决策带来…

百度搭台,千家打擂,文心杯创业大赛成投资人新宠?

“百模大战”打响&#xff0c;掀起大模型领域“创业热潮”。今年5月31日&#xff0c;百度启动“文心杯”创业大赛&#xff08;后简称“大赛”&#xff09;&#xff0c;不到1个月报名时间&#xff0c;吸引近1000个项目激烈角逐&#xff0c;在知名投资人和AI专家的权威评审和层层…

.Net6 Core Web API 配置 log4net + MySQL

目录 一、导入NuGet 包 二、添加配置文件 log4net.config 三、创建MySQL表格 四、Program全局配置 五、帮助类编写 六、效果展示 小编没有使用依赖注入的方式。 一、导入NuGet 包 ---- log4net 基础包 ---- Microsoft.Extensions.Logging.Log4Net…

go逆向符号恢复

前言 之前一直没怎么重视&#xff0c;结果发现每次遇到go的题都是一筹莫展&#xff0c;刷几道题练习一下吧 准备 go语言写的程序一般都被strip去掉符号了&#xff0c;而且ida没有相关的签名文件&#xff0c;没办法完成函数名的识别与字符串的定位&#xff0c;所以第一步通常…

HCIP——BGP反射器及联邦

BGP反射器及联邦 一、路由反射器1、路由反射器的角色2、路由反射规则3、路由反射器下的防环Originator_IDCluster_List应用举例配置方法 二、联邦1、联邦概念2、联邦的配置 路由反射器和联邦是两种专门针对IBGP水平分割设计的解决方案&#xff0c;我们依次来看下这两种技术 一…

基于 Llama2 和 OpenVINO™ 打造聊天机器人

点击蓝字 关注我们,让开发变得更有趣 作者 | 英特尔 AI 软件工程师 杨亦诚 指导 | 英特尔 OpenVINO 布道师 武卓博士 排版 | 李擎 基于 Llama2 和 OpenVINO™ 打造聊天机器人 Llama 2是 Meta 发布了其最新的大型语言模型&#xff0c;Llama2 是基于 Transformer 的人工神经网络&…

SpringCloudAlibaba之Nacos服务的发现与注册中心(一)

一&#xff1a;搭建nacos服务 在windows上搭建&#xff1a; 下载nacos &#xff0c;我在本地下载的是2.1.0 Releases alibaba/nacos (github.com)https://github.com/alibaba/Nacos/releases SpringCloudAlibaba &#xff0c;SpringCoud及Spring Boot之间版本的对应关系在以…

大麦订单生成器 大麦一键生成订单截图

后台一键生成链接&#xff0c;独立后台管理 教程&#xff1a;修改数据库config/Conn 不会可以看源码里有教程 下载程序&#xff1a;https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3

ACID特性、CAP理论、BASE原则详解

一、ACID 事务&#xff08;transaction&#xff09;&#xff1a;用户定义的一系列执行SQL的操作&#xff0c;这些操作要么完全执行&#xff0c;要么都不执行。 关系型数据库中的事务具有ACID特性 原子性(Atomicity)一致性&#xff08;Consistency&#xff09;隔离性&#xf…

红外NEC通信协议

一、NEC简介 红外(Infrared&#xff0c;IR)遥控是一种无线、非接触控制技术&#xff0c;常用于遥控器、无线键盘、鼠标等设备之间的通信。IR协议的工作原理是&#xff0c;发送方通过红外线发送一个特定的编码&#xff0c;接收方通过识别该编码来执行相应的操作。 IR协议是指红外…

JDK, JRE和JVM之间的区别和联系

JDK, JRE和JVM是与Java编程语言相关的三个重要的概念&#xff0c;它们分别代表Java Development Kit&#xff08;Java开发工具包&#xff09;、Java Runtime Environment&#xff08;Java运行时环境&#xff09;和Java虚拟机&#xff08;Java Virtual Machine&#xff09;。它们…

PHP8的运算符-PHP8知识详解

运算符是可以通过给出的一或多个值&#xff08;用编程行话来说&#xff0c;表达式&#xff09;来产生另一个值&#xff08;因而整个结构成为一个表达式&#xff09;的东西。 PHP8的运算符有很多&#xff0c;按类型分有一元运算符、二元运算符、三元运算符。 一元运算符只对一…