2016-12-14 3 views
0

私は、32ビットと64ビットの両方のシステムでCLRを介して割り当てることができるメモリの最下位ブロックの最下部に到達しようとしています。 32ビットシステムでは、4バイトのチャンクに割り当てられ、64ビットでは8バイトのチャンクに割り当てられます。 trueの場合、Int32は64ビットシステムで8バイトのアドレス空間を必要としますか?.NET CLR最も小さいメモリ割り当て(32/64ビット)

+0

CLRはオブジェクトのインスタンスごとに割り当てません。代わりに、必要に応じて大きなセグメントに割り当てられ、オブジェクトを保持するために使用されます。 –

答えて

1

次のコードをチェックした場合:あなたは、このことから

7:   public Int16 A = 1; 
mov   rcx,qword ptr [rbp+50h] 
mov   word ptr [rcx+24h],1 

8:   public Int32 B = 2; 
mov   rcx,qword ptr [rbp+50h] 
mov   dword ptr [rcx+18h],2 

9:   public Int64 C = 3; 
mov   ecx,3 
movsxd  rcx,ecx 
mov   rax,qword ptr [rbp+50h] 
mov   qword ptr [rax+8],rcx 

10:   public UInt16 D = 4; 
mov   rcx,qword ptr [rbp+50h] 
mov   word ptr [rcx+26h],4 

11:   public UInt32 E = 5; 
mov   rcx,qword ptr [rbp+50h] 
mov   dword ptr [rcx+1Ch],5 

12:   public UInt64 F = 6; 
mov   ecx,6 
movsxd  rcx,ecx 
mov   rax,qword ptr [rbp+50h] 
mov   qword ptr [rax+10h],rcx 

13:   public short G = 7; 
mov   rcx,qword ptr [rbp+50h] 
mov   word ptr [rcx+28h],7 

14:   public int H = 8; 
mov   rcx,qword ptr [rbp+50h] 
mov   dword ptr [rcx+20h],8 
mov   rcx,qword ptr [rbp+50h] 

ことができます。

public class Numbers 
{ 
    public Int16 A = 1; 
    public Int32 B = 2; 
    public Int64 C = 3; 
    public UInt16 D = 4; 
    public UInt32 E = 5; 
    public UInt64 F = 6; 
    public short G = 7; 
    public int H = 8; 
} 

逆アセンブリビューで見たときに、ターゲットプラットフォームとしてのx64を使用すると、次の指示をもたらすことコンパイルして実行しますそれがデータ型に応じて2,4,8バイトを割り当てることを確認してください。それはそれがプロセッサーの言葉遣いの塊で割り当てることではない、Windowsの単語は常に16ビット、ダブルワードは常に32ビット、そしてx64では4倍の単語を持つ。あなたがアドレスメモリ内のスペースとどのような値がアップ積層さを表示することができ、それを証明するために

![Memory block allocations

今、あなたはCLRによって管理されるように、すべてのメモリから、これは常にではないことに注意しなければなりません予測可能な行動。私の例から分かるように、Int64、UInt64では8バイト、Int32、UInt32、intでは4バイト、UInt16とshortでは2バイトしか割り当てられませんでした。

私たちは、このようなこのようなバイトまたはブール値などでも少ない数、使用した場合:

7:   public byte I = 10; 
mov   rcx,qword ptr [rbp+50h] 
mov   byte ptr [rcx+8],0Ah 

8:   public bool J = true; 
mov   rcx,qword ptr [rbp+50h] 
mov   byte ptr [rcx+9],1 

は、今ではバイトを使用し、1バイトのみを使用しています:私たちは別の結果を得る

public class Numbers 
{ 
    public byte I = 10; 
    public bool J = true; 
} 

を一人あたり

Allocation of 2 bytes

オブジェクトは、64ビットの塊でヒープ上に住んでいる: Object viewed on the heap

CLRがメモリ内にこのように、これを整理するように、それは常にではありませんが。 ヒープマップからわかるように、CLRはオブジェクトの64バイトのチャンクを割り当て、そこにすべてのオブジェクトピースを収めようとします。それはできるだけ多くの巧みさを使ってそうする。

これはいくつかの異なるバージョンを試しましたが、割り当てスペースは動作に依存し、CLRがあまりにも小さすぎると、別の場所に再割り当てしてポインタを移動します。たとえば、アドレススペースの最初の8バイトが使用されます3を保持するために、最初の4バイトにオブジェクト関連のデータの一部があり、8バイトを他のデータと共有します。そして、それが「C」の価値を保持するスペースを必要とするまで、それを続けます。それをする1つの方法は、占有スペースを得るためにCをシフトすることができるかどうかを確認することです。

質問に答えるには、割り当てられる最小のチャンクはアプリケーションによって異なります。また、CLRがプログラムのメモリを整理する方法も異なります。あなたのタイプはメモリの大部分として考えるべきではなく、それらのサイズがそれらの最大値または最小値を保持するのに必要な最大メモリを表すと考えるべきです。

大文字小文字の目安は、型が必要とする最大必要スペースをバイトに丸めたと考えることですが、CLRがこれをすべて管理するので、心配する必要はありません。 .NETでのメモリの考慮事項は、値の種類ではなく、オブジェクトの作成とライフサイクル管理に焦点を当てる必要があります。

+0

ローカル変数としてこれらの項目を割り当てたので、ヒープ上ではなくスタック上にあります。 IMHO、ヒープ上で、オーバーヘッドは重要です。一方で、配列を割り当てることは非常に効率的です。なぜなら配列には個々のアイテムではなくヘッダのみがあるからです。 –

+0

.NETデータ型に定義された長さがあるため、32ビットと64ビットの間に大きな違いはありません。 Int16は常に16ビットになります。 –

+0

これらは、メインからインスタンス化されたクラスのパブリックフィールドです。彼らはスタックにはない、彼らはヒープ上のオブジェクト内に住んでいます。 x32とx64の違いは、64ビットのデータ型に2つのdwordを割り当てるのではなく、qwordsを使用し、他の命令を使ってそれらを操作するということです。 – Espen