搜索大小大于阈值的对象
search objects with size larger then a threshold
class 之一在 .NET 堆中存在许多对象,这是通过以下 sos 命令发现的。
!dumpheap -stat -type MyClass
Statistics:
MT Count TotalSize Class Name
00007ff8e6253494 1700 164123 MyNameSpace.MyClass
我需要找到 ObjSize 大于 5 MB 的那些对象的实例。我知道我可以使用以下方法列出所有 1700 个 MyClass 实例的 objsize。
.foreach (res {!DumpHeap -short -MT 00007ff8e6253494 }) {.if ( (!objsize res) > 41943040) {.echo res; !objsize res}}
使用上面的脚本,尽管存在大于 5MB 的对象实例,但我没有得到任何结果。我认为问题可能是 objsize 的输出如下
20288 (0x4f40) bytes
它是一个字符串,因此很难与任何阈值进行比较。我怎样才能让这个脚本只列出 objsize 大于 5MB 的对象?
在 WinDbg 中创建复杂的脚本很容易出错。在这种情况下,我切换到 PyKd,这是一个使用 Python.
的 WinDbg 扩展
下面我只补你的拼图缺失的部分,也就是不对的部分:
.if ( (!objsize res) > 41943040) {.echo res; !objsize res}
这是我的起点:
0:009> !dumpheap -min 2000
Address MT Size
00000087c6041fe8 000007f81ea5f058 10158
00000087d6021018 000007f81ea3f1b8 8736
00000087d6023658 000007f81ea3f1b8 8192
00000087d6025658 000007f81ea3f1b8 16352
00000087d6029638 000007f81ea3f1b8 32672
你可以这样写一个脚本(没有错误处理!)
from pykd import *
import re
import sys
objsizeStr = dbgCommand("!objsize "+sys.argv[1])
number = re.search("= (.*)\(0x", objsizeStr)
size = int(number.group(1))
if size > 10000:
print sys.argv[1], size
并在循环中使用它:
0:009> .foreach (res {!dumpheap -short -min 2000}) { !py c:\tmp\size.py ${res}}
00000087c6041fe8 10160
00000087d6021018 37248
00000087d6023658 27360
00000087d6025658 54488
00000087d6029638 53680
请注意 !objsize
的大小与 !dumpheap
的大小有何不同。只是为了交叉检查:
0:009> !objsize 00000087d6023658
sizeof(00000087d6023658) = 27360 (0x6ae0) bytes (System.Object[])
另请参阅 ,了解如何使用 expr()
改进脚本,以便您可以传递表达式等。我现在的做法是输出十进制大小,但这并不明确。可能你想输出一个0n
前缀来表示清楚
正如史蒂夫评论的那样 !dumpeap 需要一个最小和最大参数,使用这些参数应该可以在本地完成
0:004> !DumpHeap -type System.String -stat
Statistics:
MT Count TotalSize Class Name
6588199c 1 12 System.Collectionsxxxxx
65454aec 1 48 System.Collectionsxxxxx
65881aa8 1 60 System.Collectionsxxxxx
6587e388 17 596 System.String[]
6587d834 168 5300 System.String
Total 188 objects
0:004> !DumpHeap -type System.String -stat -min 0n64 -max 0n100
Statistics:
MT Count TotalSize Class Name
6587e388 3 212 System.String[]
6587d834 9 684 System.String
Total 12 objects
0:004> !DumpHeap -type System.String -min 0n64 -max 0n100
Address MT Size
01781280 6587d834 76
01781354 6587d834 78
01781478 6587e388 84
017816d8 6587d834 64
01781998 6587d834 78
017819e8 6587d834 70
01781a30 6587d834 82
01782974 6587d834 78
01782a6c 6587d834 90
01782c7c 6587d834 68
01783720 6587e388 64
01783760 6587e388 64
Statistics:
MT Count TotalSize Class Name
6587e388 3 212 System.String[]
6587d834 9 684 System.String
Total 12 objects
操纵最大,最小值我们可以微调到一个或两个对象
一个例子,我们在上侧有 1 个额外的对象,在下侧有 2 个额外的对象
来自前面的输出(15 个对象对 12 个对象)
0:004> !DumpHeap -type System.String -min 0n62 -max 0n106
Address MT Size
01781280 6587d834 76
01781354 6587d834 78
017813e8 6587d834 62
01781478 6587e388 84
017816d8 6587d834 64
01781898 6587d834 106
01781998 6587d834 78
017819e8 6587d834 70
01781a30 6587d834 82
01782974 6587d834 78
01782a6c 6587d834 90
01782c7c 6587d834 68
01783720 6587e388 64
01783760 6587e388 64
01783e4c 6587d834 62
Statistics:
MT Count TotalSize Class Name
6587e388 3 212 System.String[]
6587d834 12 914 System.String
Total 15 objects
如果出于某种原因同时需要地址和大小,可以随时使用 awk
0:004> .shell -ci "!DumpHeap -type System.String -min 0n62 -max 0n106" awk "{print $1,$3 }"
Address Size
01781280 76
01781354 78
017813e8 62
01781478 84
017816d8 64
01781898 106
01781998 78
017819e8 70
01781a30 82
01782974 78
01782a6c 90
01782c7c 68
01783720 64
01783760 64
01783e4c 62
class 之一在 .NET 堆中存在许多对象,这是通过以下 sos 命令发现的。
!dumpheap -stat -type MyClass
Statistics:
MT Count TotalSize Class Name
00007ff8e6253494 1700 164123 MyNameSpace.MyClass
我需要找到 ObjSize 大于 5 MB 的那些对象的实例。我知道我可以使用以下方法列出所有 1700 个 MyClass 实例的 objsize。
.foreach (res {!DumpHeap -short -MT 00007ff8e6253494 }) {.if ( (!objsize res) > 41943040) {.echo res; !objsize res}}
使用上面的脚本,尽管存在大于 5MB 的对象实例,但我没有得到任何结果。我认为问题可能是 objsize 的输出如下
20288 (0x4f40) bytes
它是一个字符串,因此很难与任何阈值进行比较。我怎样才能让这个脚本只列出 objsize 大于 5MB 的对象?
在 WinDbg 中创建复杂的脚本很容易出错。在这种情况下,我切换到 PyKd,这是一个使用 Python.
的 WinDbg 扩展下面我只补你的拼图缺失的部分,也就是不对的部分:
.if ( (!objsize res) > 41943040) {.echo res; !objsize res}
这是我的起点:
0:009> !dumpheap -min 2000
Address MT Size
00000087c6041fe8 000007f81ea5f058 10158
00000087d6021018 000007f81ea3f1b8 8736
00000087d6023658 000007f81ea3f1b8 8192
00000087d6025658 000007f81ea3f1b8 16352
00000087d6029638 000007f81ea3f1b8 32672
你可以这样写一个脚本(没有错误处理!)
from pykd import *
import re
import sys
objsizeStr = dbgCommand("!objsize "+sys.argv[1])
number = re.search("= (.*)\(0x", objsizeStr)
size = int(number.group(1))
if size > 10000:
print sys.argv[1], size
并在循环中使用它:
0:009> .foreach (res {!dumpheap -short -min 2000}) { !py c:\tmp\size.py ${res}}
00000087c6041fe8 10160
00000087d6021018 37248
00000087d6023658 27360
00000087d6025658 54488
00000087d6029638 53680
请注意 !objsize
的大小与 !dumpheap
的大小有何不同。只是为了交叉检查:
0:009> !objsize 00000087d6023658
sizeof(00000087d6023658) = 27360 (0x6ae0) bytes (System.Object[])
另请参阅 expr()
改进脚本,以便您可以传递表达式等。我现在的做法是输出十进制大小,但这并不明确。可能你想输出一个0n
前缀来表示清楚
正如史蒂夫评论的那样 !dumpeap 需要一个最小和最大参数,使用这些参数应该可以在本地完成
0:004> !DumpHeap -type System.String -stat
Statistics:
MT Count TotalSize Class Name
6588199c 1 12 System.Collectionsxxxxx
65454aec 1 48 System.Collectionsxxxxx
65881aa8 1 60 System.Collectionsxxxxx
6587e388 17 596 System.String[]
6587d834 168 5300 System.String
Total 188 objects
0:004> !DumpHeap -type System.String -stat -min 0n64 -max 0n100
Statistics:
MT Count TotalSize Class Name
6587e388 3 212 System.String[]
6587d834 9 684 System.String
Total 12 objects
0:004> !DumpHeap -type System.String -min 0n64 -max 0n100
Address MT Size
01781280 6587d834 76
01781354 6587d834 78
01781478 6587e388 84
017816d8 6587d834 64
01781998 6587d834 78
017819e8 6587d834 70
01781a30 6587d834 82
01782974 6587d834 78
01782a6c 6587d834 90
01782c7c 6587d834 68
01783720 6587e388 64
01783760 6587e388 64
Statistics:
MT Count TotalSize Class Name
6587e388 3 212 System.String[]
6587d834 9 684 System.String
Total 12 objects
操纵最大,最小值我们可以微调到一个或两个对象
一个例子,我们在上侧有 1 个额外的对象,在下侧有 2 个额外的对象
来自前面的输出(15 个对象对 12 个对象)
0:004> !DumpHeap -type System.String -min 0n62 -max 0n106
Address MT Size
01781280 6587d834 76
01781354 6587d834 78
017813e8 6587d834 62
01781478 6587e388 84
017816d8 6587d834 64
01781898 6587d834 106
01781998 6587d834 78
017819e8 6587d834 70
01781a30 6587d834 82
01782974 6587d834 78
01782a6c 6587d834 90
01782c7c 6587d834 68
01783720 6587e388 64
01783760 6587e388 64
01783e4c 6587d834 62
Statistics:
MT Count TotalSize Class Name
6587e388 3 212 System.String[]
6587d834 12 914 System.String
Total 15 objects
如果出于某种原因同时需要地址和大小,可以随时使用 awk
0:004> .shell -ci "!DumpHeap -type System.String -min 0n62 -max 0n106" awk "{print $1,$3 }"
Address Size
01781280 76
01781354 78
017813e8 62
01781478 84
017816d8 64
01781898 106
01781998 78
017819e8 70
01781a30 82
01782974 78
01782a6c 90
01782c7c 68
01783720 64
01783760 64
01783e4c 62