【问题标题】:Is it possible to create "SystemStackError: stack level too deep" errors without recursion?是否可以在没有递归的情况下创建“SystemStackError:堆栈级别太深”错误?
【发布时间】:2016-11-01 13:39:03
【问题描述】:

考虑以下 irb 交互:

2.1.1 :001 > def do_it
2.1.1 :002?>   do_it
2.1.1 :003?> end
 => :do_it 
2.1.1 :004 > do_it
SystemStackError: stack level too deep

在这个例子中,它是检测出栈用尽的确定性还是真的用尽了栈?不使用递归是否可以产生这个错误?

【问题讨论】:

  • 我实在想不出这个知识的实际应用,但我很好奇……

标签: ruby recursion stack


【解决方案1】:

它确实达到了它的最大堆栈限制......

def do_it x=1
  puts "Do it #{x}"
  do_it x+1
end
do_it

以下是对 Ruby 堆栈限制的合理解释:How to increase stack size for a ruby app. Recursive app getting: Stack level too deep (SystemStackError)


Ruby 堆栈细节总结

礼貌@gregspurrier:

  • v1.8.x 使用 C 堆栈
  • v1.9.x 使用带有自己堆栈的虚拟内存
  • v2.0.0 这个VM限制可以通过RUBY_THREAD_VM_STACK_SIZE设置

【讨论】:

    【解决方案2】:

    它实际上耗尽了堆栈上的空间。 每个方法调用都需要堆栈上的一些空间。你可以有这样的代码:

    def method_1
      method_2
    end
    def method_2
      method_3
    end
    ...
    ...
    def method_123456
      method_123457
    end
    
    method_1
    

    不涉及递归,但它仍然会在某些时候耗尽堆栈空间。

    【讨论】:

      【解决方案3】:

      在这个例子中,它是检测出栈用尽的确定性还是真的用尽了栈?

      它实际上用完了堆栈。事实上,由于halting problem,计算机科学的核心问题之一,在一般情况下“检测到堆栈耗尽的确定性”是不可能的。

      不使用递归是否可能产生此错误?

      当然。只需定义很多方法,每个方法都调用下一个:

      20000.times do |n|
        define_method :"foo_#{n}" do
          puts "Called #{__method__}"
          send :"foo_#{n+1}"
        end
      end
      
      foo_0
      # -> Called foo_0
      # -> Called foo_1
      # -> Called foo_2
      # -> Called foo_3
      # ...
      # -> Called foo_4931
      # -> SystemStackError: stack level too deep
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-10
        • 2013-10-05
        • 2014-10-25
        相关资源
        最近更新 更多