为什么堆栈内存限制系统之间的差异很大?

时间:2015-06-13 01:18:04

标签: ruby linux bash recursion ulimit

我为在Ubuntu中运行的Ruby 2.1编写了一个算法实现。该算法最容易表达利用递归。最初Ruby由于问题和实现的大内存需求而提高了"堆栈级别太深的SystemStack" 异常。为了允许算法完成,我使用以下命令来增加允许的堆栈大小:

export RUBY_THREAD_VM_STACK_SIZE=16000000

ulimit -s 128000

请注意,必须运行上述两个命令。 RUBY_T​​HREAD_VM_STACK_SIZE 的单位是字节, ulimit 的单位是kBytes。因此 RUBY_T​​HREAD_VM_STACK_SIZE 限制为~16MBytes, ulimit 限制为~128MBytes。如果我将这两个限制减少了一半,那么算法就会在没有例外的情况下完成。

有人可以解释为什么这些限制相差〜8?

我已经检查了我能够做到的事情并且它似乎并不是因为其中一个单位是kbits而不是kBytes。谢谢!

1 个答案:

答案 0 :(得分:0)

我相信ulimit需要更大,因为Ruby的函数调用的样板。

/vm_eval.c中,我们看到了这一点:

  • rb_call0 - 这用于执行Ruby的功能。它接受6个参数。
  • 这反过来调用vm_call0,它接受​​7个参数。
  • 这反过来调用vm_call0_body接受3个参数。
  • 这反过来调用vm_exec(位于vm.c),接受1个参数。
  • 此时我有点迷失,但它会调用vm_exec_core和其他很多东西。

尽管如此,从这个层次结构中我们看到Ruby只是为了这个函数调用而在栈上推了很多:地址到至少5个函数和至少17个参数。这是88个字节。

那是系统堆栈。 Ruby的VM堆栈完全不同,属于Ruby的可执行文件,而不是由系统管理。它只包含Ruby为了执行函数而需要维护的结构,而没有因Ruby的代码结构而被推送到系统堆栈上的附带样板。