加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Windbg Extension NetExt 使用指南 ---- 挖掘你想要的数据 Manag

发布时间:2020-12-14 02:37:00 所属栏目:大数据 来源:网络整理
导读:摘要 : NetExt中有两个比较常用的命令可以用来分析heap上面的对象. 一个是!wheap,另外一个是!windex. !wheap 这个命令可以用于打印出heap structure信息. heap 上 object汇总后的信息. 这个命令也可以按照一些条件过滤出objects,不过执行速度比较慢. 在这一

摘要 : NetExt中有两个比较常用的命令可以用来分析heap上面的对象. 一个是!wheap,另外一个是!windex.

!wheap 这个命令可以用于打印出heap structure信息. heap 上 object汇总后的信息. 这个命令也可以按照一些条件过滤出objects,不过执行速度比较慢. 在这一点上,更推荐!windex.
!windex是一个非常常用的命令. 这个命令可以用来查找heap上面实现某个interface,继承某个abstract class 或者class的对象. 这个命令执行之后,也会缓存做过index后的对象,可以加快类似命令的之行速度. 同时也有非常酷炫的功能,可以批量的从同一类型的object中显示出个别字段.

!wheap

!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),StartSeg(0000000155660000)
        [2]:AllocStart(0000000155660068),StartSeg(0000000155660000)
        [3]:AllocStart(00000001d5660068),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),StartSeg(0000000195660000)
        [1]:AllocStart(0000000195660080),StartSeg(0000000195660000)
        [2]:AllocStart(0000000195660068),StartSeg(0000000195660000)
        [3]:AllocStart(00000001e5660068),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)

View Code

 

- detailsonly 的目的是打印出来Heap的structure的信息. Object仅仅打印前500个. 如果要打印出的Heap上所有的对象,则要使用参数 –nothrottle,不过这一命令的运行时间会略长.

用-start 以及 –end 参数,可以打印出一个范围内的object的数据.

用 –mt <string>参数,可以打印出指定的MethodTable值的objects. 类似于命令!gcheap –mt <addr>


!wheap的显示结果会统计出Heap上Object的一些汇总信息. 这些信息是按照对象类型进行分类,一条数据表示一个对象类型.

第一列是其中一个object的地址,如果有多个对象是相同类型,仅仅显示第一个.

第二列是这个类型的对象的MethodTable的地址.

第三列是这个类型的总共使用了多少virtual memory. 在做high memory 的场景的CASE的情况下,可以通过这个值快速找到占用virtual memory 最高的对象类型.

第四列是这个类型的数量.

第五列是这个类型的名称



!wheap

…….

0000000195747d18 000007fef0b9c768       36   1 0 System.Int32[]
0000000195747d40 000007fee679a850       96   1 0 System.Collections.Generic.Dictionary`2+Entry[[System.Xml.XmlQualifiedName,[System.Xml.Schema.SchemaAttDef,System.Xml]][]
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]][]
0000000195747e80 000007fee679fd20       88   1 0 System.Xml.Schema.XmlSchemaObjectTable+XmlSchemaObjectEntry[]
0000000195747ed8 000007fee67a1e60       32   1 0 System.Xml.Schema.XmlSchemaObjectTable+ValuesCollection



!windex

!windex是一个非常常用的命令. 这个命令不但可以早heap中挖掘你所需要的某个类型的数据. 最有用处的地方是,可以用来查找heap上面实现某个interface,可以加快类似命令的之行速度.

下面SHOW一下!windex比较有趣的功能,通过WINDBG的UI将heap上个object展示成树形结构. 这样的做法比较形象的对各种对象进行分析.

首先在windbg中运行!windex -tree的命令. 这个命令会快速对heap上的object做index. 然后生成一个临时文件在本地. 同时也生成了一条命令.



0:000> !windex -tree
Starting indexing at 20:19:06 PM
Indexing finished at 20:19:07 PM
7,098,503 Bytes in 77,156 Objects
Index took 00:00:01
Copy,paste and run command below:
.cmdtree C:UserssonicguoAppDataLocalTempHEAE0D6.tmp


将这个命令COPY & PASTE 到命令行上执行. 然后会弹出另外一个窗口,如下图. 这个图的效果已经非常有点接近Visual Studio中检查object的窗口效果了.



这个时候可以double click 某一条记录. 会显示出该条记录的详情.


0:000> !windex -mt 000007FEE79EFA20
Index is up to date
 If you believe it is not,use !windex -flush to force reindex
00000001556ebc68 000007fee79efa20 System.ServiceModel.BasicHttpBinding      112   0 1
00000001556f2b88 000007fee79efa20 System.ServiceModel.BasicHttpBinding      112   0 1


如果双击的不是这个类型,而是该类型下面某一个field,那么会显示出所有这个类型的每一个字段的值. 例如这里BasicHttpBinding有两个. 我想知道每一个BasicHttpBinding的name. 那么只要双击这个name,就会把两个BasicHttpBinding的名字都打印出来.

这个方式非常适合快速调查某一个类型的特定字段的值.


0:000> .foreach({$addr} {!windex -short -mt 000007FEE79EFA20}){.echo Address: {$addr}; !wselect name from {$addr}}
Address: 00000001556ebc68[System.ServiceModel.BasicHttpBinding]
System.String name = 00000001556ccbd8 wsHttpBindingConfiguration
Address: 00000001556f2b88[System.ServiceModel.BasicHttpBinding]
System.String name = 00000001556ce118 basicHttpBindingConfigurationJava


!windex 还支持模糊查询. 例如,执行下面这个命令就可以把所有后缀为BasicHttpBinding的对象都打印出来.


0:000> !windex -type *.BasicHttpBinding
Index is up to date
 If you believe it is not,use !windex -flush to force reindex
00000001556ebc68 000007fee79efa20 System.ServiceModel.BasicHttpBinding      112   0 1
00000001556f2b88 000007fee79efa20 System.ServiceModel.BasicHttpBinding      112   0 1



配合 !wfrom 来使用,可以从过滤出来的对象中找到某一个指定的字段,前提是要知道字段名称.

0:000> !wfrom -type *.BasicHttpBinding select name
name: wsHttpBindingConfiguration
name: basicHttpBindingConfigurationJava

2 Object(s) listed


这个显示结果虽然很爽,但是没有能够看到对象的地址,略微不足. 为了弥补这个不足,可以使用额外的参数 $addr() 来解决.

0:000> !wfrom -type *.BasicHttpBinding select $addr(),name
calculated: 00000001556EBC68
name: wsHttpBindingConfiguration
calculated: 00000001556F2B88
name: basicHttpBindingConfigurationJava


不仅如此,还可以用$a()的参数来添加别名,使得输出结果可读性更强.


0:000> !wfrom -type *.BasicHttpBinding select $a("Address",$addr()),$typename(),name
Address: 00000001556EBC68
calculated: System.ServiceModel.BasicHttpBinding
name: wsHttpBindingConfiguration
Address: 00000001556F2B88
calculated: System.ServiceModel.BasicHttpBinding
name: basicHttpBindingConfigurationJava

2 Object(s) listed


原文地址: http://www.cnblogs.com/developersupport/p/Debugging-NetExt-Dump-Heap.html


关注我们的方法:
1.点击文章标题下的“dotNET跨平台”蓝字,或者在微信搜索“opendotnet”,加关注
2.老朋友点击点击右上角“……”标志分享到朋友圈

3. 欢迎扫描我们的二维码(长按下面的二维码图片、并选择识别图中的二维码)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读