摘要 :
NetExt中有两个比较常用的命令可以用来分析heap上面的对象. 一个是!wheap, 另外一个是!windex.
!wheap 这个命令可以用于打印出heap structure信息. heap 上 object汇总后的信息. 这个命令也可以按照一些条件过滤出objects, 不过执行速度比较慢. 在这一点上, 更推荐!windex.
!windex是一个非常常用的命令. 这个命令可以用来查找heap上面实现某个interface, 继承某个abstract class 或者class的对象. 这个命令执行之后, 也会缓存做过index后的对象, 可以加快类似命令的之行速度. 同时也有非常酷炫的功能, 可以批量的从同一类型的object中显示出个别字段.
!wheap 这个命令可以用于打印出heap structure信息. 以及heap object的汇总后的信息. 加上参数 –detailsonly, 正如他的名字一样, 可以打印出详细的信息.
它可以显示出的Heap的数量, 由于这个CLR RUTIME使用的GC Mode是Server Mode (1). 那么Heap的数量会根据Processor的数量有所不同. 这里能够看到Heap的数量是2个.
关于GC 类型的区别, 可以参考下面的链接
- http://blogs.msdn.com/b/clyon/archive/2004/09/08/226981.aspx
- https://msdn.microsoft.com/en-us/library/cc165011(v=office.11).aspx
- http://blogs.msdn.com/b/clyon/archive/2005/02/04/367419.aspx
从输出结果可以看出来每个Managed Heap都有自己的一段地址. 如果Heap的size比较大, 还会包含多个Segment. 每个Segment的最大值都是固定的. 最大值值由很多因素决定. 不同的环境和配置时, 这个值会不一样. 当一个Segment将要分配满的时候, 会创建出一个新的Segment. 这个Segment 会缓慢增长, 直到长满为止.
这个命令也会提示GC Heap 上不同Generation代上的object的数量. 比较特别的是 Generation 3. 我们所认识的Generation 3.
0:000> !wheap -detailsonly Heaps: 2 <-- heap 的数量 --> Server Mode: 1 <-- GC Mode, 1表示是Server Mode --> Heap [0]: <-- 第一个Heap --> Allocated: 0000000155a56fe8 Card Table: 00000000027ea6b0 Ephemeral Heap Segment: 0000000155660000 Finalization Fill Pointers: 000000c28007cd40 Heap Address: 0000000000e1e790 Lowest Address: 0000000155660000 Highest Address: 00000001f5660000 Generation Addresses: [0]:AllocStart(0000000155793728),AllocCxtLimit(0000000000000000),AllocCtxPtr(0000000000000000),StartSeg(0000000155660000) [1]:AllocStart(0000000155660080),AllocCxtLimit(0000000000000000),AllocCtxPtr(0000000000000000),StartSeg(0000000155660000) [2]:AllocStart(0000000155660068),AllocCxtLimit(0000000000000000),AllocCtxPtr(0000000000000000),StartSeg(0000000155660000) [3]:AllocStart(00000001d5660068),AllocCxtLimit(0000000000000000),AllocCtxPtr(0000000000000000),StartSeg(00000001d5660000) Segments: Segment: 0000000155660000 Start: 0000000155660068 End: 0000000155981340 HiMark: 0000000155a56fe8 Committed: 0000000155a61000 Reserved: 0000000195660000 Next: 0000000000000000 <-- 第一个Segment, 由于有第二个Segment已经创建出来, 可以猜测这个Segment已经快分配完. 用End的地址减去Start的地址能够算出一个Segment的大小. 这里是64MB. --> Segment: 00000001d5660000 Start: 00000001d5660068 End: 00000001d569bf10 HiMark: 00000001d569bf10 Committed: 00000001d56a1000 Reserved: 00000001e5660000 Next: 0000000000000000 Heap [1]: Allocated: 0000000195907af8 Card Table: 00000000027ea6b0 Ephemeral Heap Segment: 0000000195660000 Finalization Fill Pointers: 000000c28007cd40 Heap Address: 0000000000e20db0 Lowest Address: 0000000155660000 Highest Address: 00000001f5660000 Generation Addresses: [0]:AllocStart(000000019573e270),AllocCxtLimit(0000000000000000),AllocCtxPtr(0000000000000000),StartSeg(0000000195660000) [1]:AllocStart(0000000195660080),AllocCxtLimit(0000000000000000),AllocCtxPtr(0000000000000000),StartSeg(0000000195660000) [2]:AllocStart(0000000195660068),AllocCxtLimit(0000000000000000),AllocCtxPtr(0000000000000000),StartSeg(0000000195660000) [3]:AllocStart(00000001e5660068),AllocCxtLimit(0000000000000000),AllocCtxPtr(0000000000000000),StartSeg(00000001e5660000) Segments: Segment: 0000000195660000 Start: 0000000195660068 End: 0000000195907af8 HiMark: 0000000195907af8 Committed: 0000000195911000 Reserved: 00000001d5660000 Next: 0000000000000000 Segment: 00000001e5660000 Start: 00000001e5660068 End: 00000001e5660080 HiMark: 00000001e5660080 Committed: 00000001e5661000 Reserved: 00000001f5660000 Next: 0000000000000000 Heap Areas: Area [0000000155660068]: 0000000155660068-0000000155660080 ( 24) Heap: 0 Generation: 2 Large: 0 <-- 表示 24个对象处于Generation 2 --> Area [0000000155660080]: 0000000155660080-0000000155793728 ( 1259176) Heap: 0 Generation: 1 Large: 0 Area [0000000155793728]: 0000000155793728-0000000155a61000 ( 2939096) Heap: 0 Generation: 0 Large: 0 Area [0000000195660068]: 0000000195660068-0000000195660080 ( 24) Heap: 1 Generation: 2 Large: 0 Area [0000000195660080]: 0000000195660080-000000019573e270 ( 909808) Heap: 1 Generation: 1 Large: 0 Area [000000019573e270]: 000000019573e270-0000000195911000 ( 1912208) Heap: 1 Generation: 0 Large: 0 Area [00000001d5660068]: 00000001d5660068-00000001d569bf10 ( 245416) Heap: 0 Generation: 3 Large: 1 <-- 表示 245416个对象处于Generation 3, 即Large Object Heap --> Area [00000001e5660068]: 00000001e5660068-00000001e5660080 ( 24) Heap: 1 Generation: 3 Large: 1 0000000155660068 0000000000e111d0 24 0 2 Free 0000000155660080 0000000000e111d0 24 0 1 Free 0000000155660098 0000000000e111d0 24 0 1 Free 00000001556600b0 000007fef0b96cb8 160 0 1 System.Exception 0000000155660150 000007fef0b96f10 160 0 1 System.OutOfMemoryException 00000001556601f0 000007fef0b96f98 160 0 1 System.StackOverflowException 0000000155660290 000007fef0b97020 160 0 1 System.ExecutionEngineException 0000000155660330 000007fef0b970a8 160 0 1 System.Threading.ThreadAbortException 00000001556603d0 000007fef0b970a8 160 0 1 System.Threading.ThreadAbortException ..... 0000000195747da0 000007fee67a1e60 32 1 0 System.Xml.Schema.XmlSchemaObjectTable+ValuesCollection 0000000195747dc0 000007fee67a1f28 56 1 0 System.Xml.Schema.XmlSchemaObjectTable+XSOEnumerator 0000000195747df8 000007fef0b9c768 36 1 0 System.Int32[] 0000000195747e20 000007fee67a2048 96 1 0 System.Collections.Generic.Dictionary`2+Entry[[System.Xml.XmlQualifiedName, System.Xml],[System.Xml.Schema.XmlSchemaObject, System.Xml]][] 0000000195747e80 000007fee679fd20 88 1 0 System.Xml.Schema.XmlSchemaObjectTable+XmlSchemaObjectEntry[] 0000000195747ed8 000007fee67a1e60 32 1 0 System.Xml.Schema.XmlSchemaObjectTable+ValuesCollection 00000001d5660068 0000000000e111d0 24 0 3 Free 00000001d5660080 000007fef0b9adf8 8192 0 3 System.Object[] ..... This output was throttled. Only the first 500 objects of each heap range has been shown. Use -nothrottle to list all objects or any limiting parameter (-type for example)
- detailsonly 的目的是打印出来Heap的structure的信息. Object仅仅打印前500个. 如果要打印出的Heap上所有的对象, 则要使用参数 –nothrottle, 不过这一命令的运行时间会略长.