Gieno DEBUGGING : TroubleShoot For OutOfMemory |
||
Problem: .load [path]\sos
3. Run dumpheap !dumpheap -stat
It will show statistics for the objects on the heap in a nice little summary divided in tho four columns. 1 The method table of the object
2 The number of objects of this type on the heap 3 The total size of these objects in bytes 4 The name of the object typeBe careful not to omit the -stat parameter. If you do then Windbg will dump the address of each object in the entire heap to your screen, which will be a lot of information to say the least. 0:000> !dumpheap -stat
Statistics: MT Count TotalSize Class Name 7a787cc4 1 12 System.IO.FileSystemWatcher+FSWAsyncResult 7a75904c 1 12 System.Diagnostics.OrdinalCaseInsensitiveComparer 7a7575cc 1 12 System.CodeDom.Compiler.CodeDomConfigurationHandler 7a7571a8 1 12 System.Net.DefaultCertPolicy 7a75661c 1 12 System.Diagnostics.TraceListenerCollection 7a755834 1 12 System.Diagnostics.PerformanceCounterCategoryType ![]() ![]() ![]() ![]() ![]() 68a66a88 227,559 12,743,304 System.Web.UI.WebControls.Literal 68a2f7fc 399,272 14,373,792 System.Web.UI.ControlCollection 68a92e2c 768,731 33,824,164 System.Web.UI.Control+OccasionalFields 68a884a0 641,952 38,517,120 System.Web.UI.LiteralControl 79124228 879,515 43,394,976 System.Object[] 790fa3e0 1,431,594 122,806,484 System.String Total 10,389,625 objects, Total size: 463,313,540 So in this particular dump I have 1,431,594 strings whose total size is 122 MBytes, 879,515 Objects with a total size of 43 MBytes, etc. 0:000> !dumpheap -type System.Web.UI.LiteralControl
Address MT Size Gen 023ea0a8 68a884a0 60 2 System.Web.UI.LiteralControl 023ea0e4 68a884a0 60 2 System.Web.UI.LiteralControl 023ea374 68a884a0 60 2 System.Web.UI.LiteralControl 023ea460 68a884a0 60 2 System.Web.UI.LiteralControl 023ea510 68a884a0 60 2 System.Web.UI.LiteralControl 023eab3c 68a884a0 60 2 System.Web.UI.LiteralControl ![]() ![]() ![]() ![]() 023fe31c 68a884a0 60 2 System.Web.UI.LiteralControl 023fe414 68a884a0 60 2 System.Web.UI.LiteralControl 023fe4c4 68a884a0 60 2 System.Web.UI.LiteralControl 023fe500 68a884a0 60 2 System.Web.UI.LiteralControl As you can see each LiteralControl is 60 bytes in size. Like I said before that's the size of the object structure alone, not it's referenced objects and properties. We now pick the address of one of the LiteralControls and execute the !dumpobj command (!do for short). This gives us the following result:
Cool, now we can take a look at the specifics. For example the value of the text-property, which is located in the string down at the bottom with address 02238664. To get it's value, simply perform a !do on the address: 0:000> !do 02238664
Name: System.String MethodTable: 790fa3e0 EEClass: 790fa340 Size: 158(0x9e) bytes GC Generation: 2 (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll) String: </td> </tr> </table> <!-- end of content table --> Fields: MT Field Offset Type VT Attr Value Name 790fed1c 4000096 4 System.Int32 0 instance 71 m_arrayLength 790fed1c 4000097 8 System.Int32 0 instance 70 m_stringLength 790fbefc 4000098 c System.Char 0 instance 3c m_firstChar 790fa3e0 4000099 10 System.String 0 shared static Empty >> Domain:Value 000f0d00:790d6584 0011a720:790d6584 << 79124670 400009a 14 System.Char[] 0 shared static WhitespaceChars >> Domain:Value 000f0d00:01d413b8 0011a720:01d44f80 << Okay, so we can see that the string contains some data to close off a table. We can also take a look at the other properties for the object and examine them if we wish. But there is another command that is really useful... 0:000> !help objsize
------------------------------------------------------------------------------- !ObjSize [<Object address>] With no parameters, !ObjSize lists the size of all objects found on managed threads. It also enumerates all GCHandles in the process, and totals the size of any objects pointed to by those handles. In calculating object size, !ObjSize includes the size of all child objects in addition to the parent. For example, !DumpObj lists a size of 20 bytes for this Customer object: 0:000> !do a79d40 Name: Customer MethodTable: 009038ec EEClass: 03ee1b84 Size: 20(0x14) bytes (C:\pub\unittest.exe) Fields: MT Field Offset Type Attr Value Name 009038ec 4000008 4 CLASS instance 00a79ce4 name 009038ec 4000009 8 CLASS instance 00a79d2c bank 009038ec 400000a c System.Boolean instance 1 valid but !ObjSize lists 152 bytes: 0:000> !ObjSize a79d40 sizeof(00a79d40) = 152 ( 0x98) bytes (Customer) This is because a Customer points to a Bank, has a name, and the Bank points to an Address string. You can use !ObjSize to identify any particularly large objects, such as a managed cache in a web server.
0:000> !objsize 023ea0a8
sizeof(023ea0a8) = 456918136 ( 0x1b3c0478) bytes (System.Web.UI.LiteralControl) 456 MBytes! How is that possible? Well if you scroll up to where we ran the !do command on the LiteralControl, you'll see that the control holds a reference to the page. The page in turn has a reference to the cache, and before long we'll have referenced almost the entire heap. 1 !dumpheap
2 !dumpobj 3 !objsize Over and out |
||
![](https://img2024.cnblogs.com/blog/35695/202407/35695-20240713070336838-1837943664.jpg)