troushoo

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

  1. --/--/--(--) --:--:--|
  2. スポンサー広告

[sos]!ObjSize:オブジェクトのサイズを表示

WinDbg等で使用できる.NET用のデバッガエクステンションsosのコマンド!ObjSizeについて記述します。
!ObjSizeを利用すると、オブジェクトのサイズを表示させることができます。

今回使用するアプリ
以下の単純なアプリを利用して!ObjSizeの利用例を見てみます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace MyObjSize
{
    class Program
    {
        class MyClass1
        {
            int int1 = 1;
            int int2 = 2;
            MyClass2 mc2 = new MyClass2();
        }
 
        class MyClass2
        {
            int int3 = 3;
            int int4 = 4;
        }
 
        static void Main(string[] args)
        {
            MyClass1 mc1 = new MyClass1();
            Console.ReadLine(); //デモ用
        }
    }
}
ReadLine()で止まっているときのダンプを取得し調査してみます。

!ObjSize
!ObjSize <オブジェクトのアドレス> でオブジェクトのサイズを表示できます。一点注意点は!ObjSizeはメンバ変数が参照しているオブジェクトのサイズを含んだ形で表示されます。
たとえば、MyClass1のオブジェクトmcに対しては以下の等式が成り立ちます。

   !ObjSize <mc1のアドレス> = <mc1のサイズ> + <mc2のサイズ>

mc1はmc2への参照をメンバ変数に持っているため、!ObjSize <mc1のアドレス>の結果には、mc2のサイズも含まれるということになります。

以下は実際の結果です。上記の等式のようになっていることがわかります。
(0249bafcはMyClass1のオブジェクトのアドレスです。詳細なログは後述します。)

0:000> !ObjSize 0249bafc
sizeof(0249bafc) =          36 (        0x24) bytes (MyObjSize.Program+MyClass1)
0:000> !DumpObj 0249bafc
Name:        MyObjSize.Program+MyClass1
MethodTable: 002938bc
EEClass:     002914a4
Size:        20(0x14) bytes //mc1のサイズは20バイト
File:        c:\users\seven\documents\visual studio 2010\Projects\MyObjSize\MyObjSize\bin\Debug\MyObjSize.exe
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
70a52ad4  4000001        8         System.Int32  1 instance        1 int1
70a52ad4  4000002        c         System.Int32  1 instance        2 int2
00293934  4000003        4 ....Program+MyClass2  0 instance 0249bb10 mc2
0:000> !DumpObj 0249bb10 //mc2のサイズを調べる
Name:        MyObjSize.Program+MyClass2
MethodTable: 00293934
EEClass:     00291960
Size:        16(0x10) bytes //mc2のサイズは16バイト
File:        c:\users\seven\documents\visual studio 2010\Projects\MyObjSize\MyObjSize\bin\Debug\MyObjSize.exe
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
70a52ad4  4000004        4         System.Int32  1 instance        3 int3
70a52ad4  4000005        8         System.Int32  1 instance        4 int4

上記の等式に当てはめると以下のようになります。

36 (= !ObjSize 0249bafc) = 20 (= !DumpObj 0249bafc) + 16 (= !DumpObj 0249bb10)

詳細なログ
1. ReadLine()で止まっているときのダンプを取得します。
(補足) 32bitの.NETアプリのダンプを取るには32bitのタスクマネージャーでダンプを取る必要があります。詳細は、以前のブログ: .NETの64bit OS上の32bitプロセスのダンプの取得方法をご参照ください。
 

2. WinDbgでダンプを開きます。
(補足).NETの32bitアプリのダンプは、32ビットのWinDbgで開く必要があります。
 
3. MyClass1をヒープから探します。
0:000> .symfix c:\sym
0:000> .reload
.........................
0:000> .loadby sos clr
0:000> !DumpHeap -type MyClass1
Address       MT     Size
0249bafc 002938bc       20    
total 0 objects
Statistics:
      MT    Count    TotalSize Class Name
002938bc        1           20 MyObjSize.Program+MyClass1
Total 1 objects
4. MyClass1オブジェクトに対し!DumpObjを実行します。
0:000> !DumpObj 0249bafc
Name:        MyObjSize.Program+MyClass1
MethodTable: 002938bc
EEClass:     002914a4
Size:        20(0x14) bytes
File:        c:\users\seven\documents\visual studio 2010\Projects\MyObjSize\MyObjSize\bin\Debug\MyObjSize.exe
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
70a52ad4  4000001        8         System.Int32  1 instance        1 int1
70a52ad4  4000002        c         System.Int32  1 instance        2 int2
00293934  4000003        4 ....Program+MyClass2  0 instance 0249bb10 mc2
5. MyClass1オブジェクトに対し!ObjSizeを実行します。
0:000> !ObjSize 0249bafc
sizeof(0249bafc) =           36 (        0x24) bytes (MyObjSize.Program+MyClass1)


リンク
・MSDNによる!ObjSize含むsos.dllの説明
http://msdn.microsoft.com/en-us/library/bb190764.aspx
・Getting started with windbg – partII
http://blogs.msdn.com/b/johan/archive/2007/11/26/getting-started-with-windbg-part-ii.aspx


  1. 2012/05/19(土) 15:27:05|
  2. SOS・Psscor2/Psscor4
  3. | トラックバック:0
  4. | コメント:0
<<[sos]!finalizequeue:Freachable キューの状態表示 | ホーム | Visual Studioでプロファイル(CPUサンプリング)>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://troushoo.blog.fc2.com/tb.php/55-afd44997
この記事にトラックバックする(FC2ブログユーザー)

スポンサーリンク

最新記事

月別アーカイブ

カテゴリ

ツール (92)
ネットワーク (76)
Visual Studio (56)
SOS・Psscor2/Psscor4 (25)
WinDbg (25)
Linux (23)
Azure (17)
Tips (20)
英語 (1)
About Me (1)
未分類 (0)

全記事表示リンク

全ての記事を表示する

検索フォーム

RSSリンクの表示

リンク

このブログをリンクに追加する

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。