【问题标题】:Why the large difference between stack memory limit systems?为什么堆栈内存限制系统之间存在巨大差异?
【发布时间】:2015-08-29 02:53:58
【问题描述】:

我为在 Ubuntu 中运行 Ruby 2.1 的课程编写了一个算法实现。该算法最容易使用递归来表达。最初,由于问题和实现需要大量内存,Ruby 提出了“stack level too deep 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。谢谢!

【问题讨论】:

  • 你在使用线程吗?

标签: ruby linux bash recursion ulimit


【解决方案1】:

我认为 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 的代码结构而被推送到系统堆栈上的样板。

【讨论】:

    猜你喜欢
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 2018-08-24
    • 2017-11-12
    • 2023-03-03
    • 2012-01-29
    • 2013-05-21
    相关资源
    最近更新 更多