• Basic Windbg 1. SOSBasics(再续)


    我们的查看对象之旅,还远没有结束。继续按照前前一篇的代码来扒皮。上节讲的是通过!dso,找到所有stack上的东西,下面我们看heap上的东西。首先,整体上先来了解一下。

    我们这里会用一个新命令,叫做!eeheap(叹号+eeheap)。它有两个参数,一个叫-gc,一个叫-loader。后者,葡萄在他的书里面写过一个case,因为load的东西太多,造成了内存巨量的碎片,导致OOM出现。对于前者,会简单的把gc的状态给我们列出来。当然,你也可以不加参数。我们先看!eeheap -gc
    0:000> !eeheap -gc
    Number of GC Heaps: 1
    generation 0 starts at 0x01521018
    generation 1 starts at 0x0152100c
    generation 2 starts at 0x01521000
    ephemeral segment allocation context: none
     segment    begin allocated     size
    004cccc0 790d8620  790f7d8c 0x0001f76c(128876)
    01520000 01521000  01577ff4 0x00056ff4(356340)
    Large object heap starts at 0x02521000
     segment    begin allocated     size
    02520000 02521000  02523250 0x00002250(8784)
    Total Size   0x789b0(494000)
    ------------------------------
    GC Heap Size   0x789b0(494000)

    几点注意的。
    1、GC有三个generation,分别是0、1、2
    2、整个gc heap的size是:494000,大概50k左右。
    3、看我们抓到的那个dump文件,大小是55,252,827字节,55K左右。说明大部分都是托管资源占用的内存。

    这个命令大家先记着点,我们看另外一个命令:!dumpheap。这个命令会把托管堆上所有的东西都扒出来。so,我就不把输出放到这里了。我们只看最后几行:
    79104368      388         9312 System.Collections.ArrayList
    7912d8f8     1164        60448 System.Object[]
    7912dae8       55        85940 System.Byte[]
    790fd8c4     2581       224408 System.String
    Total 7097 objects

    托管堆上一共7097个对象,呵呵,吃惊吧?我们那么点代码,居然有这么多东西!(很多东西不是咱自己的。。。),其中字符串一共占用了224408个字节,就是22k左右,够大的了!
    !dumpheap有几个参数,都很有用,我们分别来看。(继续用帮助,如果你勤快的话:!help dumpheap)
    首先看第一个,-stat参数。顾名思义,它会按照托管资源的类型group by,每个不同的类型的信息都列出来。下面粘一点内容出来:
    0:000> !dumpheap -stat
    total 7097 objects
    Statistics:
          MT    Count    TotalSize Class Name
    791334a8        1           12 System.Collections.Generic.GenericEqualityComparer`1[[System.String, mscorlib]]
    7911cd80        1           12 System.Collections.Hashtable+KeyCollection

    。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
    7910f2ac        4          240 System.Reflection.AssemblyName
    。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
    79104368      388         9312 System.Collections.ArrayList
    7912d8f8     1164        60448 System.Object[]
    7912dae8       55        85940 System.Byte[]
    790fd8c4     2581       224408 System.String
    Total 7097 objects


    从这个输出,我们能看到,-stat是按照TotalSize来排序的(但是这个size不准,一定要注意!!!)。如果我们想看上面的那个System.Reflection.AssemblyName
    ,怎么看呢?注意最左面的列,是method table,中间是个数。那么我们要看一下,这里就要用另外一个参数了,-mt,后面跟上上面的methodtable。如:
    0:000> !dumpheap -mt 7910f2ac
     Address       MT     Size
    0155c7a0 7910f2ac       60    
    0155c928 7910f2ac       60    
    0155cf00 7910f2ac       60    
    0155d058 7910f2ac       60    
    total 4 objects
    Statistics:
          MT    Count    TotalSize Class Name
    7910f2ac        4          240 System.Reflection.AssemblyName
    Total 4 objects
    一共有4个object,地址分别是0155c7a0、0155c928、0155cf00和0155d058 ,利用上面一篇的!do,连续几次,就能看到东西了。

    一般来讲,!dumpheap -stat和!dumpheap -mt <methodtable>是很有用的,尤其在我们分析high cpu/ high memory的时候。这个以后拿具体例子来讲。
    我们继续看!dumpheap的第三个参数 -min,这个命令的好处是,只列出比指定大小大的对象出来。如,我们想看一下大小在8000个字节以上的对象,那么可以这么看:
    0:000> !dumpheap -min 8000
     Address       MT     Size
    790ddd94 790fd8c4     9280    
    01522c20 7912dae8    21200    
    01527ef0 790fd8c4    42396    
    01532504 7912d8f8     8208    
    0153d174 7912dae8    38940    
    0156ae60 7912dae8     9012    
    total 6 objects
    Statistics:
          MT    Count    TotalSize Class Name
    7912d8f8        1         8208 System.Object[]
    790fd8c4        2        51676 System.String
    7912dae8        3        69152 System.Byte[]
    Total 6 objects
    一共有6个对象,其中1个object数组,2个字符串,3个byte数组。比较奇怪,两个字符串怎么这么大?居然51k大小?看一下啊,!dumpheap -mt 790fd8c4 -min 8000
    0:000> !dumpheap -mt 790fd8c4 -min 8000
     Address       MT     Size
    790ddd94 790fd8c4     9280    
    01527ef0 790fd8c4    42396    
    total 2 objects

    哦,第二个居然占了42k,真是晕倒!看一下,!do -nofields 01527ef0 ,部分输出如下:
    String: <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <mscorlib>
    <security>
    <policy>
    <PolicyLevel version="1">
    <SecurityClasses>
    <SecurityClass Name="AllMembershipCondition"

    一共42k,很长地。。。这是一个xml文档,应该是CLR自己维护的。

    还有一个参数,-type,这个可以指定我们要看的东西。如string,如hashtable等。可以这么看:!dumpheap -type String,这里注意的是,String严格对应.NET里面的数据类型,so,是大小写敏感的。同理,hashtable你要写成:!dumpheap -type Hashtable。

    这部分字数少了点,不过写的也比较累。下面我们做一个总结,利用这几个命令,先来看一个实际问题。

  • 相关阅读:
    杂项题的基本解题思路——1、文件操作与隐写
    虚拟机Kali Linux安装VMware Tools
    HTTP协议分析
    exe可执行文件和源代码文件asm
    编译和链接
    承上启下
    汇编语言(王爽)学习记录_第八章
    汇编语言(王爽)学习记录_第七章
    解决jsp中连接不了数据库的问题
    汇编语言(王爽)学习记录_第六章
  • 原文地址:https://www.cnblogs.com/juqiang/p/1023236.html
Copyright © 2020-2023  润新知