2016-06-27 3 views
2

WinDbgを使用して.NETプロセスのメモリダンプを解析しています。ヒープ上のすべてのSystem.Int32変数のサイズが24バイトと報告されています。ここでは変数の1に該当するDumpObjコールの例です:WinDbgでSystem.Int32変数が24バイトとして表示されるのはなぜですか?

0:000> !DumpObj /d 00000061c81c0e80 
Name:  System.Int32 
MethodTable: 00007fff433f37c8 
EEClass:  00007fff42e30130 
Size:  24(0x18) bytes 
File:  C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll 
Fields: 
       MT Field Offset     Type VT  Attr   Value Name 
00007fff433f37c8 4000456  8   System.Int32 1 instance    141 m_value 

私の知る限りでは、サイズ可能System.Int32は4バイトであると考えられます。この不一致の原因は何ですか?

+4

通常のSkeetはこれについてのブログ記事を書いています。 64ビットの場合、24バイトは「最小」サイズです –

+1

[こちら](https://codeblog.jonskeet.uk/2011/04/05/of-memory-and-strings/)はその投稿です(参考用です)。 –

+1

ヒープ上にある場合は、ボックス化されています。つまり、通常のオブジェクトオーバーヘッド(x64ではオブジェクトあたり8バイト、x64ではオブジェクトあたり16バイト)を持ち、4/8バイト境界にアライメントする必要があり、12Bになりますx86では24B、x64では24Bです。 – Groo

答えて

3

ヒープ上の任意のオブジェクトへのオーバーヘッドがあります。 32ビットのMS.NETランタイムでは、これは8バイトで、64ビットでは16バイトです(免責事項:これは契約上のものではなく、今後、または.NETランタイムに準拠した実装で変更される可能性があります) 。

intはボックス化されているため、16バイトのオーバーヘッドになります。したがって、合計で20バイトが使用されると予想される場合があります。 64ビットシステムでは、オブジェクト(および構造体)が8バイトの境界に埋め込まれていることを除いて、実際にはintあたり24バイトになります。

対照的に、structを16個の整数で使用する場合は、16 + 4 * 16 = 80バイトのメモリしか使用せず、整数あたり合計5バイトです。

さらに、これは実装の詳細なので、頼りになるものではありません。有効な.NETランタイムでは、単一のintを1 MiBのメモリに格納することは可能ですが、すべての契約上の動作に準拠していれば、コンパクトな表現でもインターナショナルでも格納できますタイプの。実際のMSランタイム実装と比較しても非常に単純化されています。たとえば、オブジェクトが十分に大きくなると、オーバーヘッドが増えます。

+0

実際、配列は多少異なります。 'int'配列はx64で' 28 + length * 4'をとります。 – Groo

+0

@Grooええ、私はそれを投稿した後に2番目のことを気付いた:)あなたはまた、長さとランクを必要とする:D – Luaan

2

それがDDまたはDQアドレスを行い、それぞれのx86/x64のための12バイトまたはオブジェクトごとに24バイトの暗黙のオーバーヘッドがあり、あなたのINT32は、2番目のDWORDまたはQWORD
で立ち往生

0:004> .shell -ci "!DumpObj /d 01c72360" grep -i size 
    Size:  12(0xc) bytes 
    .shell: Process exited 
    0:004> dd 01c72360 l4 
    01c72360 5890c770 000001b5 80000000 5890afb0 
    0:004> .shell -ci "!DumpObj /d 01c72360" grep -i method 
    MethodTable: 5890c770 
    .shell: Process exited 
    0:004> .shell -ci "!DumpObj /d 01c72360" grep -i value 
      MT Field Offset     Type VT  Attr Value Name 
    5890c770 400044f  4   System.Int32 1 instance  437 m_value 
    .shell: Process exited 
    0:004> ? 1b5 
    Evaluate expression: 437 = 000001b5 
を参照してくださいint32型のサイズではありません

dumpobj

のx86の

actualsizereqdfor(L"stream\0") = 7 * sizeof(wchar_t) == 7 * 2 == 0n14;  
sizeof(method table)           == 0n04; 
sizeof(sizeof(L"stream))          == 0n04;  
sizeof(padding ?? terminator ?? whatever ??)     == 0n04; 
so total size             == 0n26 

結果にWideStringに "ストリーム" を解剖することができます離れてINT32残し

生ディスプレイ

0:004> db 01c73ad0 l1a 
01c73ad0 b0 af 90 58 06 00 00 00-73 00 74 00 72 00 65 00 ...X....s.t.r.e. 
01c73ae0 61 00 6d 00 00 00 00 00-00 00     a.m....... 
関連する問題