我的堆是否被分段了?

9
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
实际上,拥有很多的空闲空间更像是没有或几乎没有碎片化的迹象。 - VVS
2
输出结果显示该应用程序有50315个可用内存块,而且大部分都不到半兆字节。这看起来比较分散。 - Brian Rasmussen
1个回答

5
所以...我们知道我们有一个碎片化的堆。下一个问题是:是什么导致了这种碎片化?是什么阻止了这些空闲对象的释放?我读到的建议是检查自由空间后面的对象:
  1. !dumpheap -stat

  2. 转储Free对象的方法表:!dumpheap -mt 000db8e8

  3. 从列表中选择一个Free对象进行更详细的检查:!dumpobj 0x2003b0b0

  4. 记录对象的大小

  5. 转储它后面的下一个对象:!dumpobj 0x2003b0b0+1000

  6. 找到持有引用的对象!gcroot 0x2003b0b0+1000

  7. 转储找到的对象的gchandle。

我通常会陷入这个兔子洞里,因为我对.NET API的知识有限。这是调试问题的正确方式吗?
Jeff

1
我已经查看了哪个堆是碎片化的。我最初使用!eeheap -gc来获取要搜索的段的基础,但是SOSEX(http://www.stevestechspot.com/SOSEXV2NowAvailable.aspx)有一些专门针对此问题的命令。看起来它在大对象堆中(这是预期的,因为它从未压缩),在第二代堆中也有一定程度的碎片化。我不关心第零代,第一代没有碎片化。我认为你的意思是尝试找出在碎片化之后分配的对象,然后从那里开始回溯,以查看是什么导致了碎片化,即!dumpobj 0x2003b0b0+1000。 - Keith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接