Part of each method state is a local memory pool. Memory can be explicitly allocated from the local memory pool using the
localloc
instruction. All memory in the local memory pool is reclaimed on method exit,and that is the only way local memory pool memory is reclaimed (there is no instruction provided to free local memory that was allocated during this method invocation). The local memory pool is used to allocate objects whose type or size is not known at compile time and which the programmer does not wish to allocate in the managed heap. Because the local memory pool cannot be shrunk during the lifetime of the method,a language implementation cannot use the local memory pool for general-purpose memory allocation.
CLR在哪里分配这个内存池?是托管堆,线程堆栈等?
解决方法
StackOverflowException is thrown if there is insufficient memory to service the request.
你只有一种获得SOE的方法:它需要从堆栈中分配.
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
子eax,0A8h指令从ESP寄存器(堆栈指针)中减去0xa8 = 168 = 42×4字节,mov esp,eax指令调整堆栈指针.所以是的,这肯定来自堆栈.