Dot-Net

我的堆是碎片化的嗎

  • November 19, 2018
0:000> !dumpheap -stat
total 1755874 objects
Statistics:
MT    Count    TotalSize Class Name
7b9b0c64        1           12 System.Windows.Forms.Layout.TableLayout+ColumnSpanComparer
....
7933303c    14006      4926456 System.Collections.Hashtable+bucket[]
65246e00      804      4982192 System.Data.RBTree`1+Node[[System.Int32, mscorlib]][]
054c55f0    44240      5662720 DevExpress.Utils.AppearanceObject
793040bc    98823      7613156 System.Object[]
793308ec   293700     55820016 System.String
002435f0    50315    138631888      Free
Total 1755874 objects

Fragmented blocks larger than 0.5 MB:
   Addr     Size      Followed by
15a195c8    0.8MB         15ae3950 System.Collections.ArrayList
15d81468    1.6MB         15f23708 System.String
15f23984    1.0MB         16029ae4 System.String
... about 7 more objects here
1ee51764    0.5MB         1eedbaa4 System.WeakReference
1f0df96c    2.4MB         1f34d4b0 System.String
1f3e1ca8    3.7MB         1f79afc4 System.WeakReference

我一直在閱讀有關固定和碎片的資訊。考慮到大量的可用空間,它在我看來是支離破碎的。我想我現在必須追查它。

想法?回饋?

所以……我們知道我們有一個碎片堆。下一個問題是:是什麼導致了碎片化?是什麼阻止了這些自由對像被釋放?我讀過的建議是在可用空間之後檢查對象:

  1. !dumpheap -stat
  2. 轉儲Free對象的方法表:!dumpheap -mt 000db8e8
  3. 從列表中選擇一個自由對象進行更仔細的檢查:!dumpobj 0x2003b0b0
  4. 記錄對象的大小
  5. 轉儲它之後的下一個對象:!dumpobj 0x2003b0b0+1000
  6. 找到持有引用的對象!gcroot 0x2003b0b0+1000
  7. 轉儲找到的對象的 gchandle。

我通常會鑽進這個兔子洞,而我對 .NET API 的有限知識在這裡失敗了。這是調試問題的正確方法嗎?

傑夫

引用自:https://stackoverflow.com/questions/870723