I'm investigating the memory leak issue with PerfMon & WinDbg. I was noticed the 'Large memory heap' counter is increased from 10MB to 37MB. After force a GC it only can reduce to 28MB.
(No matter how many time I repeate the operation(create/destroy), after GC, the large object heap is stable at 28MB).
I would like know which objects cause leak issue, so I run the WinDbg with the '!Dumpheap -min 85000' comand. Captured two snapshots, the first one was done before memory leak; The second one is after memory leak:
Before:
MT Count TotalSize Class Name
6f39fb08 1 89024 System.String
6f3a4aa0 1 107336 System.Byte[]
6f356d84 2 262176 System.Object[]
00360e4c 1 350392 System.Collections.Generic.Dictionary`2+Entry[Int64,Int32][]
6f3a2a94 3 592584 System.Int32[]
00360c24 1 727072 System.Collections.Generic.Dictionary`2+Entry[String,Int64][]
0bc78b34 4 2754488 System.Collections.Generic.Dictionary`2+Entry[Int64, AccountNode][]
00730260 10 5375572 Free
After:
MT Count TotalSize Class Name
6f39fb08 1 89024 System.String
6f3a4aa0 1 107336 System.Byte[]
6f3a55d8 2 202080 System.Collections.Hashtable+bucket[]
6f356d84 2 262176 System.Object[]
00360e4c 1 350392 System.Collections.Generic.Dictionary`2+Entry[Int64,Int32][]
00360c24 1 727072 System.Collections.Generic.Dictionary`2+Entry[String,Int64][]
6f3a2a94 4 738008 System.Int32[]
6cf02838 1 872488 System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.ComponentModel.PropertyKey, WindowsBase],[MS.Internal.ComponentModel.DependencyPropertyKind, WindowsBase]][]
0bc78b34 4 2754488 System.Collections.Generic.Dictionary`2+Entry[Int64, AccountNode][]
00730260 14 21881328 Free
Total 31 objects
Camparing these two snapshot, the most difference is the size of 'Free'. its size has increased near 16MB. Can anyone tell me what's the meaning of the 'Free', is it the free space? Is the increasement caused by fragements?
According to this article, the ‘Large Object Heap Size’ performance counter seems include free space. So in my case, there isn't have too much memory leak on large object heap, only 2MB (= 28 - 10 -16), right?
If an object is greater than or equal to 85,000 bytes in size, it's considered a large object. This number was determined by performance tuning. When an object allocation request is for 85,000 or more bytes, the runtime allocates it on the large object heap.
Small Object Heap has generations that are checked from time to time. At the end of collection this heap is fragmented so it need to be compacte. If Large Objects were in this heep it would take long time for defragmentation.
FREE indicates a block of unused memory on the heap. FREE blocks on the LOH are expected, because the LOH never gets compacted. Instead, a list of FREE space is kept for the LOH. FREE blocks on the normal GC heap, with a few exceptions, indicate fragmentation due to the pinning of objects. When the GC encounters a pinned object, compaction of the segment is halted and the memory consumed by unused objects is marked as FREE. What you're seeing on the LOH is normal. Remember that the LOH is never compacted and memory segments allocated for the LOH are never freed, so the LOH never shrinks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With