2013-10-27 8 views
6

ECMA-335、I.12.3.2.4は、以下の状態:各メソッドの状態のここで、CLRはローカルメモリプールを割り当てますか?

一部は、ローカル・メモリ・プールです。メモリは、localloc命令を使用してローカルメモリプールから明示的に割り当てることができます。ローカルメモリプール内のすべてのメモリは、メソッド終了時に再利用され、ローカルメモリプールメモリが再利用される唯一の方法です(このメソッド呼び出し中に割り当てられたローカルメモリを解放するための命令はありません)。ローカルメモリプールは、コンパイル時に型またはサイズがわからないオブジェクトと、プログラマが管理対象ヒープに割り当てることを望まないオブジェクトを割り当てるために使用されます。メソッドの存続期間中にローカルメモリプールを縮小することはできないため、言語実装は汎用メモリ割り当てに汎用メモリプールを使用できません。

ここで、CLRはこのメモリプールを割り当てますか?それはヒープ、スレッドスタックなどを管理していますか?

+0

私はどの権限でも言うことはできませんが、私にはスタック割り当てのように聞こえます。しかし、私は、実装者に大きな柔軟性を提供するために、標準で明示的にそれを要求していないと考えています。 – Dweeberly

答えて

8

これは意図的に漠然としています。これは、CLI仕様が厳格に実装する必要がないためです。これは、しかしOpcodes.LocallocのためのMSDNの記事の割れ目からピークし:

StackOverflowExceptionが要求にサービスを提供するのに十分なメモリがある場合にスローされます。

SOEを取得する方法は1つだけです。スタックから割り当てる必要があります。

C#言語では、割り当てられる場所が少なく、stackallocというキーワードが使用されます。サンプルプログラム:

class Program { 
    static unsafe void Main(string[] args) { 
     int* p = stackalloc int[42]; 
    } 
} 

は、このILを生成します:

実行時にこのマシンコードを生成し
.method private hidebysig static void Main(string[] args) cil managed 
{ 
    .entrypoint 
    // Code size  9 (0x9) 
    .maxstack 8 
    IL_0000: ldc.i4.s 42 
    IL_0002: conv.u 
    IL_0003: ldc.i4.4 
    IL_0004: mul.ovf.un 
    IL_0005: localloc     // <=== Here 
    IL_0007: pop 
    IL_0008: ret 
} // end of method Program::Main 

02E42620 push  ebp 
02E42621 mov   ebp,esp 
02E42623 sub   esp,8 
02E42626 mov   dword ptr [ebp-4],esp 
02E42629 mov   dword ptr [ebp-8],6A029823h 
02E42630 mov   eax,esp 
02E42632 test  dword ptr [esp],esp 
02E42635 sub   eax,0A8h      // <=== Here 
02E4263A mov   esp,eax 
02E4263C mov   dword ptr [ebp-4],esp 
02E4263F cmp   dword ptr [ebp-8],6A029823h 
02E42646 je   02E4264D 
02E42648 call  730CA5C0 
02E4264D lea   esp,[ebp] 
02E42650 pop   ebp 
02E42651 ret 

sub eax,0A8h命令がESPから0xa8 = 168 = 42x4バイトを減算しますレジスタ(スタックポインタ)の場合、mov esp,eax命令はスタックポインタを調整します。はい、これは間違いなくスタックから来ています。

関連する問題