一:背景1. 讲故事中秋国庆长假结束,哈哈,在老家拍了很多的短视频 , 有兴趣的可以上B站观看:https://space.bilibili.com/409524162 ,今天继续给大家分享各种奇奇怪怪的.NET生产事故,希望能帮助大家在未来的编程之路上少踩坑 。
话不多说 , 这篇看一个.NET程序集泄露导致的CLR私有堆泄露的案例,这个泄露和 JsonConvert 有关,哈哈,相信你肯定比较惊讶!
二:WinDbg 分析1. 到底是哪里的泄露首先观察一下进程的提交内存的大?。?赐ü?nbsp;!address -summary 观察 。
0:000> !address -summary--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotalFree3907dfa`63fa8000 ( 125.978 TB)98.42%<unknown>13628205`32974000 (2.020 TB)99.92%1.58%Heap81430`4042b000 (1.004 GB)0.05%0.00%Stack1860`1f8e0000 ( 504.875 MB)0.02%0.00%Image19580`09775000 ( 151.457 MB)0.01%0.00%Other90`001d7000 (1.840 MB)0.00%0.00%TEB620`0007c000 ( 496.000 kB)0.00%0.00%PEB10`00001000 (4.000 kB)0.00%0.00%--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotalMEM_MAppED312200`00a06000 (2.000 TB)98.92%1.56%MEM_PRIVATE217175`91ecd000 (22.280 GB)1.08%0.02%MEM_IMAGE19580`09775000 ( 151.457 MB)0.01%0.00%--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotalMEM_FREE3907dfa`63fa8000 ( 125.978 TB)98.42%MEM_RESERVE4509205`0fc14000 (2.020 TB)99.89%1.58%MEM_COMMIT194780`8c434000 (2.192 GB)0.11%0.00%
当前的提交内存占用了 2.19G , 进程堆占用 1G ,差不多占了一半,但不能说明就是非托管内存泄露,接下来继续观察下托管堆 。
0:000> !eeheap -gcNumber of GC Heaps: 8------------------------------Heap 7 (000001C4971013A0)generation 0 starts at 0x000001C817D201A0generation 1 starts at 0x000001C817C878D8generation 2 starts at 0x000001C817261000ephemeral segment allocation context: nonesegmentbeginallocatedsize000001C817260000000001C817261000000001C819013F980x1db2f98(31141784)Large object heap starts at 0x000001C907261000segmentbeginallocatedsize000001C907260000000001C907261000000001C9072610180x18(24)Pinned object heap starts at 0x000001C987261000000001C987260000000001C987261000000001C9872ABA500x4aa50(305744)Heap Size:Size: 0x1dfda00 (31447552) bytes.------------------------------GC Heap Size:Size: 0xba26488 (195191944) bytes.
从卦中可以看到当前的托管堆占用仅 195M , 这就更好的验证当前确实存在非托管内存泄露,由于非托管内存没有开启 ust,也没有 perfview 的etw文件 , 所以没有好的方式进一步挖掘,到这里可能就止步不前了 。
2. 到底是哪里的泄露在 C# 所处的 windows 进程中,其实有很多的堆,比如:crt堆,ntheap堆,gc堆,clr私有堆,堆外(VirtualAlloc),调试没有标准答案,不断的假设,试探,摸着石头过河,言外之意就是这个堆没问题,不代表其他堆也没有问题 , 这样想思路就比较顺畅了,我们可以看看其他的堆 , 比如这里的 CLR私有堆,使用 !eeheap -loader 观察 。
0:000> !eeheap -loaderLoader Heap:--------------------------------------...Module 00007ff846e034c0: Size: 0x0 (0) bytes.Module 00007ff846e03930: Size: 0x0 (0) bytes.Module 00007ff846e04180: Size: 0x0 (0) bytes.Module 00007ff846e047e0: Size: 0x0 (0) bytes.Module 00007ff846e04e40: Size: 0x0 (0) bytes.Total size:Size: 0x0 (0) bytes.--------------------------------------Total LoaderHeap size:Size: 0x47252000 (1193615360) bytes total, 0x1f68000 (32931840) bytes wasted.=======================================
从卦中可以看到有非常多的 module 迸射出来,估计有几万个,并且可以看到总的大小是 1.19G , 到这里基本就搞清楚了,然来是 程序集泄露 。
这里稍微补充一下 , 像这种问题早期可以使用 dotnet-counter 或者 Windows 的程序集指标 监控一下,或许你就能轻松找出原因,截图如下:
PS C:UsersAdministratorDesktop> dotnet-counters monitor -n WebApplication2
文章插图
图片
而且 dotnet-counter 还是跨平台的 , 非常实用,大家可以琢磨琢磨,接下来抽一个module 用命令 !dumpmodule -mt 00007ff846e034c0 观察下,内部到底有哪些类型 。
0:000> !dumpmodule -mt 00007ff846e034c0Name: Unknown ModuleAttributes:Reflection IsDynamic IsInMemory Assembly:000001c9e193b9e0BaseAddress:0000000000000000...Types defined in this moduleMTTypeDef Name------------------------------------------------------------------------------00007ff846e03db0 0x02000002 Types referenced in this moduleMTTypeRef Name------------------------------------------------------------------------------00007ff820ff5748 0x02000002 xxx.xxx.Json.Converters.PolymorphismConverter`100007ff820e710f8 0x02000003 xxx.xxx.Models.IApiResult0:000> !dumpmt -md 00007ff846e03db0Number of IFaces in IFaceMap: 0--------------------------------------MethodDesc TableEntryMethodDescJIT Name00007FF822F05FA8 00007ff823285b50NONE xxx.Json.Converters.PolymorphismConverter`100007FF822EFD5E8 00007ff82323b1b8NONE System.Text.Json.Serialization.JsonConverter`100007FF822EFD5F0 00007ff82323b1c8NONE System.Text.Json.Serialization.JsonConverter`100007FF8414CB978 00007ff846e03d88JIT IApiResultDynamicJsonConverter..ctor()
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 54岁歌手罗中旭被曝婚内出轨,女方公开亲密合影,曝光聊天记录
- 这一次,终于不再隐瞒了,王力宏裸打视频一经发布,网友直呼太恶心
- 微信交易记录怎么查 微信交易记录怎么查个人
- 微信怎么查询聊天记录 微信怎么查询聊天记录分析报告
- 怎么截屏微信聊天记录语音 怎么截屏微信聊天记录
- 银行逾期记录怎么处理 银行逾期记录怎么处理最有效
- 曝网红萧俊同时与30位女友交往,致多人怀孕流产,聊天记录曝光
- 这一次,消失8年的毕福剑,不再被世界宽容
- 第一次用微波炉怎么加热
- 第一次使用洗衣机需要清洗吗