我注意到每个正在运行的C程序都有一个名为[stack]的私有映射,它最初非常小(在我的机器上为128k),但会增长以容纳任何自动变量(最大为堆栈大小限制).我假设这是我的程序的调用堆栈所在的位置.
但是,它似乎没有缩小到原来的大小.有没有办法在不终止进程的情况下释放内存?
如何在内部实现C堆栈; 是什么增加了[堆栈]按需映射的大小?有些编译器生成代码,C库或操作系统?增加触发的位置在哪里?
更新:我在x86-64上使用Linux 3.0.0,gcc 4.6.1和glibc6; 因为这可能是非常具体的实现,任何有关它如何工作的信息都会没问题.
在 Linux/MMU 中(在 !MMU 中,您无法增长堆栈),堆栈在页面错误处理程序中增长。对于x86,是否增长堆栈由以下代码决定arch/x86/mm/fault.c:do_page_fault():
if (error_code & PF_USER) {
/*
* Accessing the stack below %sp is always a bug.
* The large cushion allows instructions like enter
* and pusha to work. ("enter $65535, $31" pushes
* 32 pointers and then decrements %sp by 65535.)
*/
if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) {
bad_area(regs, error_code, address);
return;
}
}
if (unlikely(expand_stack(vma, address))) {
bad_area(regs, error_code, address);
return;
}
Run Code Online (Sandbox Code Playgroud)
expand_stack()检查通常的 RLIMITS(RLIMIT_AS、RLIMIT_STACK、RLIMIT_MEMLOCK)、LSM 是否允许增长堆栈、是否存在过多的过度使用等……,最后增长堆栈。