微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – CLR在哪里分配本地内存池?

ECMA-335,I.12.3.2.4规定如下:

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在哪里分配这个内存池?是托管堆,线程堆栈等?

解决方法

这一切都是故意模糊的,因为它是一个强大的实现细节,CLI规范不想确定.它浏览了MSDN文章中的裂缝,但是:

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指令调整堆栈指针.所以是的,这肯定来自堆栈.

原文地址:https://www.jb51.cc/csharp/244109.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐