我遇到了一个问题,即在云上运行的一项使用 .Net4.8 编写的 Web 服务内存使用率过高的问题。监控工具警告内存峰值达到1.4GB。我用
ProcDump
工具转储进程的内存。转储文件大约为 1.5GB。
然后我开始用
WinDbg
分析dump文件,好吗?我做了两个分析。
首先,我运行
dumpheap –stat
命令,该命令生成以下输出。输出有数千行长,所以我在这里只显示几行:
0:000> !dumpheap -stat
Statistics:
MT Count TotalSize Class Name
00007ffce8b30b50 1 24 System.Runtime.Caching.UsageEntryRef
00007ffce8b30ae8 1 24 System.Runtime.Caching.ExpiresEntryRef
00007ffce8b2edc0 1 24 System.Runtime.Caching.ChangeMonitor[]
00007ffce742ae98 1 24 System.ComponentModel.DataAnnotations.RangeAttribute+<>c
00007ffce742ae50 1 24 System.ComponentModel.DataAnnotations.RegularExpressionAttribute+<>c
00007ffce742ae08 1 24 System.ComponentModel.DataAnnotations.RequiredAttribute+<>c
00007ffce742adc0 1 24 System.ComponentModel.DataAnnotations.StringLengthAttribute+<>c
00007ffce742ad30 1 24 System.ComponentModel.DataAnnotations.ValidationAttribute+<>c
... omit the following part
根据我的调查,
!dumpheap -stat
显示了managed heap
尺寸。就我而言,大约是 45MB(我总结了上面所有的行)。
其次,我运行命令
!address -summary
,然后它会生成以下输出。我把所有内容都贴在这里了
0:000> !address -summary
Mapping file section regions...
Mapping module regions...
Mapping PEB regions...
Mapping TEB and stack regions...
Mapping heap regions...
Mapping page heap regions...
Mapping other regions...
Mapping stack trace database regions...
Mapping activation context regions...
--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free 338 7ffe`d06bb000 ( 127.995 TB) 100.00%
<unknown> 4715 0`feb0f000 ( 3.980 GB) 83.90% 0.00%
Stack 276 0`16880000 ( 360.500 MB) 7.42% 0.00%
Image 1241 0`0e989000 ( 233.535 MB) 4.81% 0.00%
Heap 519 0`0b997000 ( 185.590 MB) 3.82% 0.00%
Other 15 0`001cd000 ( 1.801 MB) 0.04% 0.00%
TEB 92 0`000b8000 ( 736.000 kB) 0.01% 0.00%
PEB 1 0`00001000 ( 4.000 kB) 0.00% 0.00%
--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_PRIVATE 5051 1`1e9d4000 ( 4.478 GB) 94.41% 0.00%
MEM_IMAGE 1753 0`1013b000 ( 257.230 MB) 5.30% 0.00%
MEM_MAPPED 55 0`00e26000 ( 14.148 MB) 0.29% 0.00%
--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE 338 7ffe`d06bb000 ( 127.995 TB) 100.00%
MEM_RESERVE 2503 0`cdc3c000 ( 3.215 GB) 67.78% 0.00%
MEM_COMMIT 4356 0`61cf9000 ( 1.528 GB) 32.22% 0.00%
--- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal
PAGE_READWRITE 3018 0`50f9f000 ( 1.265 GB) 26.67% 0.00%
PAGE_EXECUTE_READ 128 0`09dbe000 ( 157.742 MB) 3.25% 0.00%
PAGE_READONLY 663 0`05389000 ( 83.535 MB) 1.72% 0.00%
PAGE_WRITECOPY 281 0`011ef000 ( 17.934 MB) 0.37% 0.00%
PAGE_EXECUTE_READWRITE 97 0`0072b000 ( 7.168 MB) 0.15% 0.00%
PAGE_READWRITE | PAGE_GUARD 92 0`00192000 ( 1.570 MB) 0.03% 0.00%
PAGE_EXECUTE_WRITECOPY 51 0`0014d000 ( 1.301 MB) 0.03% 0.00%
PAGE_NOACCESS 26 0`0001a000 ( 104.000 kB) 0.00% 0.00%
--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Free 21c`92440000 7dd9`6cbe0000 ( 125.849 TB)
<unknown> 21b`a3b45000 0`0fffb000 ( 255.980 MB)
Stack 45`82800000 0`003f9000 ( 3.973 MB)
Image 7ffc`d3011000 0`011df000 ( 17.871 MB)
Heap 21c`77d51000 0`00fce000 ( 15.805 MB)
Other 21b`e6ae0000 0`00181000 ( 1.504 MB)
TEB 45`80e00000 0`00002000 ( 8.000 kB)
PEB 45`80f5e000 0`00001000 ( 4.000 kB)
根据我的调查,
!address -summary
命令生成.NET进程的所有内存使用情况。但这个输出真的让我很困惑!
任何人都可以帮我解释这个输出吗?我想知道 1.4GB 内存来自哪里,例如托管堆、本机堆、堆栈或程序集。接下来我可以运行什么样的分析?
为了更好地了解内存消耗较高的位置,有必要运行基准测试或分析器来对该消耗进行详细分析。
有时,“小”代码改进可能会带来更高的性能。 (在不需要迭代值的场景中如何使用“IEnumerable”而不是“List”)。
也许一个简单的解决方案是使用 SonarQube 等代码分析器来查看它发现了哪些改进。