占托管堆的大小和它的所有对象它的、大小、对象

2023-09-07 16:06:59 作者:耀眼的阳光照不出我的思念

我调查的高内存消耗问题,我的申请。内存持续上涨了,我想知道在哪里所有内存都被消耗掉。我有一个转储文件,该文件是〜3GB大小。

I am investigating a high memory consumption issue with my application. The memory keep rising up and I would like to know out where all the memory is consumed. I have got a dump file that is ~3GB in size.

下面是!dumpheap -stat命令的输出。总的名单很长,但我只是想告诉你最大的项目,如字节[](195 MB),IdentifierChangedEventHandler(120 MB),字符串(119 MB)。这一切都没有任何地方接近添加到3GB。

Here is the output of !dumpheap -stat command. The overall list is long but I just wanted to show you the biggest items like byte[] (195 MB), IdentifierChangedEventHandler (120 MB), strings (119 MB). This all does not add up any where close to 3GB.

000007fe94169ff0   101326      7295472 System.Linq.Enumerable+WhereListIterator`1[[CommonServices.WindowsEvent.EventIDExpression+RangeExpressionCollection+RangeExpression, CommonServices]]
000007fe94237f08        1      7786800 System.Collections.Generic.Dictionary`2+Entry[[System.Int32, mscorlib],[OrderingServices.LocalCache, OrderingServices]][]
000007fef1afc3a8   202112      8084480 System.Collections.Generic.List`1[[System.Guid, mscorlib]]
000007fef1ac24c0   204144      9798912 System.Collections.ArrayList+ArrayListEnumeratorSimple
000007fef1accc50   313792     10041344 System.Guid
000007fef1ad14a0   314054     10049728 System.Security.SecureString
000007fef1ac7790   131954     11403930 System.Char[]
000007feed2f93b8     2063     11898472 System.Data.RBTree`1+Node[[System.Data.DataRow, System.Data]][]
000007fef1a87890   316978     12679120 System.Security.SafeBSTRHandle
000007fef1acc590   350337     14013480 System.Collections.ArrayList
000007fe936bdcd0   202083     14549976 OrderingServices.LocalCache
000007fe942db718   202083     16166640 System.Collections.Generic.Dictionary`2[[System.Guid, mscorlib],[System.Collections.Generic.HashSet`1[[System.Int32, mscorlib]], System.Core]]
000007feed2f5910   248683     23873568 System.Data.DataRow
000007fef1aca708   317533     25402640 System.Collections.Hashtable
000007fe942dbf60   202021     32610456 System.Collections.Generic.Dictionary`2+Entry[[System.Guid, mscorlib],[System.Collections.Generic.HashSet`1[[System.Int32, mscorlib]], System.Core]][]
000007fef1ac3838   319558     32975376 System.Collections.Hashtable+bucket[]
000007fef1a74458   307557     35724224 System.Object[]
000007feef6cc770   631242     38621784 System.Collections.Generic.HashSet`1+Slot[[System.Int32, mscorlib]][]
000007feef6cb860   631242     40399488 System.Collections.Generic.HashSet`1[[System.Int32, mscorlib]]
000007fef1ac9258   937270     48016624 System.Int32[]
000007fef1ac6508   879690    119968068 System.String
000007fef1aca690   176907    196509678 System.Byte[]
00000000002ae930   139663    520724414      Free
Total 14024120 objects
Fragmented blocks larger than 0.5 MB:
            Addr     Size      Followed by
000000008e84f490    1.6MB 000000008e9f08b8 Microsoft.Win32.SafeHandles.SafeTokenHandle
00000001878e1ca8    0.7MB 000000018798ffd8 Microsoft.Win32.SafeHandles.SafeTokenHandle
0000000187ac1070    0.7MB 0000000187b76138 System.Threading.ReaderWriterLock
0000000187d39d88    1.5MB 0000000187ec2788 System.Threading.ReaderWriterLock
0000000187f7bfe0    0.9MB 000000018805ce90 System.Threading.ReaderWriterLock
0000000188ad1b30    0.5MB 0000000188b5a190 System.Net.ListenerAsyncResult
000000018909ef98    1.0MB 00000001891a9e90 System.Net.Sockets.Socket
0000000189377440    0.6MB 0000000189417088 Microsoft.Win32.SafeHandles.SafeTokenHandle
000000018a07e428    0.7MB 000000018a1382a0 System.Threading.ExecutionContext
000000018a599610    1.2MB 000000018a6d4b50 Microsoft.Win32.SafeHandles.SafeTokenHandle
000000018bad8b30    0.7MB 000000018bb87b00 Microsoft.Win32.SafeHandles.SafeTokenHandle
000000018bb88778    1.1MB 000000018bcac050 System.Threading.ReaderWriterLock
000000018bcac618    1.3MB 000000018bdee998 Microsoft.Win32.SafeHandles.SafeTokenHandle
000000018ed68b78    1.0MB 000000018ee6c290 System.Threading.ReaderWriterLock
000000018eec5b70    0.9MB 000000018efb37a8 System.Threading.ReaderWriterLock
000000018f351930    0.7MB 000000018f40edb0 Microsoft.Win32.SafeHandles.SafeTokenHandle
000000018f469d00    0.6MB 000000018f509360 System.Net.ListenerAsyncResult
000000018f5508d8    2.8MB 000000018f824ad8 Microsoft.Win32.SafeHandles.SafeTokenHandle
000000018f917610    2.2MB 000000018fb41790 Microsoft.Win32.SafeHandles.SafeTokenHandle
000000028985e148    0.6MB 00000002898f72e0 System.Security.SafeBSTRHandle
0000000289901008    0.8MB 00000002899c3138 System.Security.SafeBSTRHandle
000000028a1e7378    0.7MB 000000028a295dd8 System.Net.ListenerAsyncResult
000000028a56a8b8    1.3MB 000000028a6c23c8 System.Threading.ReaderWriterLock
000000028a8c0a28    0.9MB 000000028a9b2b88 MonitoringServices.PerformanceCounter.PerformanceCounterDataPoint
000000028b1b80c8    0.9MB 000000028b2a6a30 System.Data.SqlClient.SNIPacket
000000028d37d7c0    0.6MB 000000028d4220f0 System.Transactions.SafeIUnknown
000000028d5f05c8    1.6MB 000000028d789b20 System.Net.ListenerAsyncResult
000000028d78ac08    2.4MB 000000028d9e7e58 System.Transactions.SafeIUnknown
000000028d9ec618    0.7MB 000000028da95c88 System.Threading.ReaderWriterLock
000000028daa5f58    1.2MB 000000028dbe2af8 System.Threading.ReaderWriterLock
000000028dbe3b00    0.7MB 000000028dc98aa0 System.Threading.ReaderWriterLock
000000028dc99aa8    1.6MB 000000028de30e40 System.String
0000000385644a88    0.7MB 00000003856eee30 Microsoft.Win32.SafeHandles.SafeWaitHandle
00000003868ecbc0    0.7MB 00000003869a18a8 System.Byte[]
00000003878d0330    0.5MB 0000000387950678 System.Threading.ReaderWriterLock
0000000387951680    1.2MB 0000000387a84b18 Microsoft.Win32.SafeHandles.SafeTokenHandle
0000000387e137d0    1.8MB 0000000387fdbb50 System.Security.SafeBSTRHandle
0000000388175388    1.5MB 00000003882ed100 System.Threading.ReaderWriterLock
00000003882ee108    0.8MB 00000003883b5b10 System.String
00000003883c5c20    0.9MB 00000003884aa8d8 System.Byte[]
00000003891fa318    1.7MB 00000003893a3e30 Microsoft.Win32.SafeHandles.SafeTokenHandle
0000000389cafe00    0.7MB 0000000389d61ff0 System.Byte[]
000000038a036238    1.0MB 000000038a135428 System.Net.ListenerAsyncResult

下面是输出!地址-summary。堆使用情况总结出1.1 GB虽然我不知道这是不是所有的托管堆上?

Here is the output of !address -summary. The Heap usage summary showing 1.1 GB although I don't know if this is all managed heap?

0:000> !address -summary
--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free                                    525      7fa`04208000 (   7.977 Tb)           99.71%
<unknown>                               917        5`8f56a000 (  22.240 Gb)  92.92%    0.27%
Heap                                    204        0`4b5af000 (   1.177 Gb)   4.92%    0.01%
Image                                  2327        0`12fc5000 ( 303.770 Mb)   1.24%    0.00%
Stack                                   701        0`0df80000 ( 223.500 Mb)   0.91%    0.00%
TEB                                     229        0`001ca000 (   1.789 Mb)   0.01%    0.00%
Other                                    19        0`001bf000 (   1.746 Mb)   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                            1717        5`e6543000 (  23.599 Gb)  98.59%    0.29%
MEM_IMAGE                              2627        0`140dc000 ( 320.859 Mb)   1.31%    0.00%
MEM_MAPPED                               54        0`017c9000 (  23.785 Mb)   0.10%    0.00%

--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE                                525      7fa`04208000 (   7.977 Tb)           99.71%
MEM_RESERVE                             736        5`2ba70000 (  20.682 Gb)  86.41%    0.25%
MEM_COMMIT                             3662        0`d0378000 (   3.253 Gb)  13.59%    0.04%

--- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal
PAGE_READWRITE                         1590        0`babd4000 (   2.918 Gb)  12.19%    0.04%
PAGE_EXECUTE_READ                       260        0`0f1ba000 ( 241.727 Mb)   0.99%    0.00%
PAGE_READONLY                           756        0`0376d000 (  55.426 Mb)   0.23%    0.00%
PAGE_WRITECOPY                          561        0`01f24000 (  31.141 Mb)   0.13%    0.00%
PAGE_EXECUTE_READWRITE                  180        0`008bd000 (   8.738 Mb)   0.04%    0.00%
PAGE_READWRITE|PAGE_GUARD               229        0`0043f000 (   4.246 Mb)   0.02%    0.00%
PAGE_EXECUTE_WRITECOPY                   85        0`0025a000 (   2.352 Mb)   0.01%    0.00%
PAGE_EXECUTE                              1        0`00003000 (  12.000 kb)   0.00%    0.00%

--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Free                                      5`ffff0000      7f8`93260000 (   7.971 Tb)
<unknown>                                 3`92f8f000        0`ed061000 (   3.703 Gb)
Heap                                      0`19010000        0`00fd0000 (  15.813 Mb)
Image                                   7fe`edfb9000        0`01368000 (  19.406 Mb)
Stack                                     0`0b8d0000        0`000fc000 (1008.000 kb)
TEB                                     7ff`ffbd4000        0`00002000 (   8.000 kb)
Other                                     0`008a0000        0`00181000 (   1.504 Mb)
PEB                                     7ff`fffdf000        0`00001000 (   4.000 kb)

最后,如果跑!eeheap -gc,它的表现〜1.6GB在所有四个GC堆。

Finally if run !eeheap -gc, its showing ~ 1.6GB in all four GC heaps.

0:000> !EEHeap -gc

Number of GC Heaps: 4
------------------------------
Heap 0 (00000000002d8aa0)
generation 0 starts at 0x000000008ff94830
generation 1 starts at 0x000000008f1157e8
generation 2 starts at 0x000000007fff1000
ephemeral segment allocation context: none
 segment     begin allocated  size
000000007fff0000  000000007fff1000  00000000935cc580  0x135db580(324908416)
Large object heap starts at 0x000000047fff1000
 segment     begin allocated  size
000000047fff0000  000000047fff1000  0000000484d38270  0x4d47270(81031792)
Heap Size:               Size: 0x183227f0 (405940208) bytes.
------------------------------
Heap 1 (0000000000abcf00)
generation 0 starts at 0x0000000190b5f3f8
generation 1 starts at 0x000000018fcb1988
generation 2 starts at 0x000000017fff1000
ephemeral segment allocation context: none
 segment     begin allocated  size
000000017fff0000  000000017fff1000  0000000193ee36f8  0x13ef26f8(334440184)
Large object heap starts at 0x000000048fff1000
 segment     begin allocated  size
000000048fff0000  000000048fff1000  00000004960eae48  0x60f9e48(101686856)
Heap Size:               Size: 0x19fec540 (436127040) bytes.
------------------------------
Heap 2 (0000000000ac78b0)
generation 0 starts at 0x000000028f89f588
generation 1 starts at 0x000000028e83ca90
generation 2 starts at 0x000000027fff1000
ephemeral segment allocation context: none
 segment     begin allocated  size
000000027fff0000  000000027fff1000  0000000292bf43d0  0x12c033d0(314586064)
Large object heap starts at 0x000000049fff1000
 segment     begin allocated  size
000000049fff0000  000000049fff1000  00000004a5b90b78  0x5b9fb78(96074616)
Heap Size:               Size: 0x187a2f48 (410660680) bytes.
------------------------------
Heap 3 (0000000000ad2c00)
generation 0 starts at 0x000000038ecddd18
generation 1 starts at 0x000000038dcb9ec8
generation 2 starts at 0x000000037fff1000
ephemeral segment allocation context: none
 segment     begin allocated  size
000000037fff0000  000000037fff1000  00000003925e93b8  0x125f83b8(308249528)
Large object heap starts at 0x00000004afff1000
 segment     begin allocated  size
00000004afff0000  00000004afff1000  00000004b55a61e8  0x55b51e8(89870824)
Heap Size:               Size: 0x17bad5a0 (398120352) bytes.
------------------------------
GC Heap Size:            Size: 0x6265f218 (1650848280) bytes.

我有两个问题。 1.反正凑!dumpheap -stat命令中列出的所有对象规模的总和。 2.是否有反正验证GC堆大小相匹配的所有对象的总规模从!dumpheap -stat,这样我可以肯定,我所有的对象都占了?

I have two questions. 1. Is there anyway of getting sum of all object sizes listed in !dumpheap -stat command. 2. Is there anyway of verify that GC heap size matches with total size of all the objects from !dumpheap -stat so that I can be sure that all my objects are accounted for?

推荐答案

首先,解决-summary 只显示这是由CreateHeap创建堆()函数,这是不.NET。 .NET使用自己的至爱,显示在输出&lt;未知&GT;

First of all, address -summary shows only heaps which are created by the CreateHeap() function, which is not .NET. .NET uses its own heaps and are shown in the output as <unknown>.

接下来你忘记添加了520 MB大小的自由的对象。这些都是在.NET堆在那里.NET对象已经在较早时间的地方,但随后被垃圾收集。这个自由空间可能或不可能在后面给出回至OS。在执行命令的时候,它是由.NET内存管理器的使用,但这位经理认为这是免费的。但从OS来看,该内存仍然在使用(保留或承诺,但是不是免费的)。

Next you forgot to add up the "Free" objects with a size of 520 MB. These are places in the .NET heap where a .NET object has been at an earlier time, but has then been garbage collected. This free space may or may not be given back to the OS later. At the time of executing the command, it was in use by the .NET memory manager, but that manager considered it to be free. From OS point of view, that memory is still in use (reserved or committed, but not free).

第三个我认为是一个错误:整体GC堆大小为1650848280,这是1.6 GB,而不是160 GB。否则就违背了&lt;未知&GT; 数目为22 GB

Third I assume that's a mistake: the overall GC heap size is 1650848280, which is 1.6 GB, not 160 GB. Otherwise it would contradict the <unknown> number which is at 22 GB.

一个问题是开放的是:如果&lt;未知&GT; 为22 GB,但只有1.6 GB通过.NET进行管理,另一部分被用作由调用其他组件虚拟()直接。这是相当不寻常的,因为的粒度的VirtualAlloc()很平静,所以没有人使用它。可能有一个用例,只要你知道自己在做什么的内存的大块。

One question is open though: if <unknown> is 22 GB, but only 1.6 GB are managed by .NET, the rest is used by other components which call VirtualAlloc() directly. That's rather unusual, because the granularity of VirtualAlloc() is very rough so nobody uses it. There may be a use case as long as you know what you're doing with those large blocks of memory.

关于你的问题:看到@SteveJohnson答案。我不确认的观察,记忆碎片是造成沉重的异步I / O。这可能是原因之一,但也有其他人也,如:固定的对象(通常与一些本土的东西相结合)。不要忘了小物件堆碎片和大对象堆碎片来区分。

Regarding your questions: see the answer by @SteveJohnson. I don't confirm the observation that memory fragmentation is caused by heavy async I/O. That might be one cause, but there are others as well, e.g. pinned objects (usually in conjunction with some native stuff). Don't forget to distinguish between small object heap fragmentation and large object heap fragmentation.

更新:

据我所知,你不能从谁分配的虚拟内存转储弄清楚。你也许可以通过设置在VirtualAlloc的断点()和打印调用栈这样做成一个输出文件,后来检查不同的调用堆栈。我从来没有在实践中做到了这一点,但下面应该是一个起点:

As far as I know, you cannot figure out from a dump who allocated the virtual memory. You might be able to do so by settings a breakpoint on VirtualAlloc() and printing the callstack into an output file and later check for different call stacks. I've never done this in practice, but the following should be a starting point:

.logopen virtualalloc.log
bp Kernel32!VirtualAlloc ".echo ANALYZE>;k;.echo <ANALYZE;g"
bp Kernel32!VirtualAllocEx ".echo ANALYZE>;k;.echo <ANALYZE;g"
g

这将创建一个断点VirtualAlloc的。当命中,将其写入一个开始标记和结束标记调用堆栈,所以输出更容易在会议结束后进行解析。它立即继续让你的应用程序希望不受超时。

This will create a breakpoint for VirtualAlloc. When hit, it writes the callstack with a start tag and an end tag, so the output is easier to parse after the session. It immediately continues so that your application is hopefully not affected by timeouts.

另一种方法是 Rohitab API监测和过滤器VirtualAlloc的。您可以在系统Servcies /存储管理/虚拟内存/ Kernel32.dll中发现的VirtualAlloc和VirtualAllocEx的。不幸的是,文件格式是不开放,所以您不能分析的结果与工具。

Another approach could be Rohitab API monitor and filter for VirtualAlloc. You find VirtualAlloc and VirtualAllocEx in System Servcies / Memory Management / Virtual Memory / Kernel32.dll. Unfortunately the file format is not open, so you can't analyze the results with a tool.

 
精彩推荐
图片推荐