C程序的堆栈是否会缩小?

lxg*_*xgr 4 c stack

我注意到每个正在运行的C程序都有一个名为[stack]的私有映射,它最初非常小(在我的机器上为128k),但会增长以容纳任何自动变量(最大为堆栈大小限制).我假设这是我的程序的调用堆栈所在的位置.

但是,它似乎没有缩小到原来的大小.有没有办法在不终止进程的情况下释放内存?

如何在内部实现C堆栈; 是什么增加了[堆栈]按需映射的大小?有些编译器生成代码,C库或操作系统?增加触发的位置在哪里?

更新:我在x86-64上使用Linux 3.0.0,gcc 4.6.1和glibc6; 因为这可能是非常具体的实现,任何有关它如何工作的信息都会没问题.

Dav*_*nan 6

它是特定于实现的,但我知道没有常用的平台可以缩小已提交的堆栈内存.堆栈按需增长是很常见的,但是一旦提交了空间,它就会保持承诺.


nin*_*alj 2

在 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 是否允许增长堆栈、是否存在过多的过度使用等……,最后增长堆栈。

  • 问题是“C 程序的堆栈会缩小吗?” (2认同)