如何在Mac OS X上使用ulimit或每个进程为C或Ruby程序更改堆栈大小?

似乎为C程序或Ruby程序(使用C堆栈)设置堆栈大小的推荐方法是在Bash shell中使用ulimit 。 但

 $ ulimit -s 8192 $ ulimit -s 16384 -bash: ulimit: stack size: cannot modify limit: Operation not permitted 

sudo也没有帮助。 有没有办法将其设置为16MB,32MB或64MB? 我认为应该有一种方法来设置每个程序调用,而不是设置系统范围的参数?

现在8192可能意味着8MB这是非常小的,如果将其与进程可以使用的数量进行比较,有时甚至高达2GB的RAM。

更新说明: ulimit -a可以显示其当前值)。

更新2:看起来似乎ulimit -s 是每个shell,如果你第一次设置它,它通常会工作。问题是你第二次设置它,然后它可能会返回一个错误)

显然,对于mac os x的堆栈大小有一个硬性限制,取自http://lists.apple.com/archives/scitech/2004/Oct/msg00124.html,这是相当古老的,我不确定它是否仍然是真的,但设置它只是调用ulimit -s hard,它的65532.或大约65 megs。

我对雪豹进行了一些测试,10.6.8,看起来确实如此。

 $ ulimit -a ... stack size (kbytes, -s) 8192 ... $ ulimit -s 65533 -bash: ulimit: stack size: cannot modify limit: Operation not permitted $ ulimit -s 65532 $ 

我也发现这个http://linuxtoosx.blogspot.com/2010/10/stack-overflow-increasing-stack-limit.html虽然我还没有测试过,所以不能真正说出来。

当应用程序消耗通常从堆中获取的内存时,堆栈通常为本地自动变量保留,这些变量存在的时间相当于函数调用的生命周期,堆是大多数持久数据存在的地方。

这是一个快速教程:

 #include  #define NUMBER_OF_BYTES 10000000 // about 10 megs void test() { char stack_data[NUMBER_OF_BYTES]; // allocating on the stack. char *heap_data = malloc(NUMBER_OF_BYTES); // pointer (heap_data) lives on the stack, the actual data lives on the heap. } int main() { test(); // at this point stack_data[NUMBER_OF_BYTES] and *heap_data have being removed, but malloc(NUMBER_OF_BYTES) persists. // depending on the calling convention either main or test are responssible for resetting the stack. // on most compilers including gcc, the caller (main) is responssible. return 0; } $ ulimit -a ... stack size (kbytes, -s) 8192 ... $ gcc mc $ ./a.out Segmentation fault $ ulimit -s hard $ ./a.out $ 

ulimit只是暂时的,您每次都必须更新它,或者更新相应的bash脚本以自动设置它。

一旦设置了ulimit,它只能降低从不boost。

系统默认堆栈大小因内核的不同版本而异。 我的10.7是16384,因此我的Mac接受了ulimit -s 16384。 您可以尝试sysctl kern.stack_size并显示只读堆栈大小。 我的是16384。
您可以查看此技术文章http://developer.apple.com/library/mac/#qa/qa1419/_index.html ,了解如何更改C程序的默认堆栈大小。 对于Ruby,因为它是一种脚本语言,所以在链接Ruby解释器时必须扩大其堆栈大小。 除了非常深的函数调用或递归,或者在堆栈中分配了非常大的数组和对象之外,您的程序不应该有很大的堆栈空间。 相反,使用堆或动态分配可以根据需要使用最多2GB的RAM。

在我看来,接受的答案并不完全正确,导致错失理解,更具体地说,最后的陈述是不正确的。

一旦设置了ulimit,它只能降低从不boost。

确实有软(可用ulimit -sulimit -Ss显示)和硬(可用ulimit -Hs显示)限制。 但是通过ulimit -s设置限制会影响软值硬值。

一旦设置了限制,它只能降低从不boost,但只要该值保持低于硬限制,就可以降低或提高软限制。

这将有效:

 # base values $ ulimit -s 100 $ ulimit -Hs 100 $ ulimit -Ss 100 # lower soft limit only $ ulimit -Ss 50 $ ulimit -s 50 $ ulimit -Hs 100 $ ulimit -Ss 50 # raise soft limit only $ ulimit -Ss 100 $ ulimit -s 100 $ ulimit -Hs 100 $ ulimit -Ss 100 # lower soft and hard limit $ ulimit -s 50 $ ulimit -s 50 $ ulimit -Hs 50 $ ulimit -Ss 50 # then impossible to raise soft limit due to hard limit $ ulimit -s 100 -bash: ulimit: stack size: cannot modify limit: Operation not permitted $ ulimit -Ss 100 -bash: ulimit: stack size: cannot modify limit: Invalid argument 

我发现使用/bin/zsh而不是/bin/sh使得这个错误消失了。

对我来说,错误发生在一个名为ulimit -s unlimited的shell脚本中。 当脚本被/bin/sh解释时(即,将#!/bin/sh作为脚本文件的第一行),它会发生此错误。 相比之下,当改变它使用zsh ,一切似乎都很好。 zsh很聪明,可以将unlimited解释为“给我操作系统让我拥有的最大限制”,并且一切都按照你的意愿运行。