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

Why the large difference between stack memory limit systems?

我在 Ubuntu 中为 Ruby 2.1 运行ning 的课程编写了一个算法的实现。该算法使用递归最容易表达。最初 Ruby 引发了 "stack level too deep SystemStack" 异常,因为问题和实现需要大量内存。为了让算法完成,我使用了以下命令来增加允许的堆栈大小:

export RUBY_THREAD_VM_STACK_SIZE=16000000

ulimit -s 128000

请注意,上面的两个命令都必须是 运行。 RUBY_THREAD_VM_STACK_SIZE的单位是bytes,ulimit的单位是kBytes。所以 RUBY_THREAD_VM_STACK_SIZE 限制是 ~16MBytes 而 ulimit 限制是~128MBytes。如果我将任一限制减少一半,则此处显示的值将无一例外地完成算法。

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

我已经检查了我能做什么,但似乎不是,因为其中一个单位是 kbits 而不是 kBytes。谢谢!

由于 Ruby 围绕函数调用的样板,我认为 ulimit 需要更大。

/vm_eval.c 中我们看到了这个:

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

尽管如此,从这个层次结构中我们看到 Ruby 仅仅为了这个函数调用就在堆栈上压了很多:指向至少 5 个函数和至少 17 个参数的地址。那是 88 个字节。

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