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

标签 ruby linux bash recursion ulimit

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

export RUBY_THREAD_VM_STACK_SIZE=16000000

ulimit -s 128000

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

有人可以解释为什么这些限制相差 ~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 的代码结构导致的被推送到系统堆栈的附带样板。

关于ruby - 为什么堆栈内存限制系统之间的差异很大?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30814202/

相关文章:

Ruby 的 `respond_to?` 在定义之后不起作用?

linux - 使用 gdbServer 进行远程调试

python - Python/Chrome/Java (linux mint) 的段错误

linux - 我如何创建一个通用的 shell 命令来退出或从执行或获取的脚本中返回?

ruby-on-rails - gem 安装ruby-audio-1.6.1错误(使用Mac OS 10.9/Homebrew)

ruby - psql 必须是扩展 plpgsql 的所有者

linux - Bash 重定向和标准输入

java - 在unix中使用.sh文件运行.jar文件

iphone - 如何将 iphone 模拟器连接到 selgrid 2?

c++ - 如何使用终端在程序之间交换数据?