首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CLR分配本地内存池的地方?

CLR分配本地内存池的地方?
EN

Stack Overflow用户
提问于 2013-10-27 15:28:25
回答 1查看 581关注 0票数 7

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

每个方法状态的一部分是一个本地内存池。可以使用localloc指令从本地内存池显式分配内存。本地内存池中的所有内存都是在方法退出时回收的,这是回收本地内存池内存的唯一方法(没有提供指令来释放在此方法调用期间分配的本地内存)。本地内存池用于分配在编译时类型或大小未知且程序员不希望在托管堆中分配的对象。由于本地内存池在方法的生存期内不能缩小,语言实现不能使用本地内存池进行通用内存分配。

CLR在哪里分配这个内存池?它是托管堆、线程堆栈吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-27 15:37:11

这都是有意模糊的,因为它是CLI规范不想确定的一个强大的实现细节。不过,它可以窥探Opcodes.Localloc MSDN文章中的漏洞:

如果内存不足,则引发StackOverflowException。

获得SOE的方法只有一种:它需要从堆栈中分配。

C#语言对于在何处分配不那么害羞,它使用stackalloc关键字。示例程序:

代码语言:javascript
复制
class Program {
    static unsafe void Main(string[] args) {
        int* p = stackalloc int[42];
    }
}

产生这个IL:

代码语言:javascript
复制
.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

它在运行时生成此机器代码:

代码语言:javascript
复制
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寄存器(堆栈指针)中减去0xa 8= 168 = 42x4字节,mov esp,eax指令调整堆栈指针。所以是的,这绝对是从堆栈中得到的。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19619768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档