且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Ruby 堆栈级别太深异常不是来自递归无限循环

更新时间:2023-10-29 23:35:10

除了经典的 program-execution-tree-too-deep 场景之外,是否还有其他情况会导致堆栈级别过深异常?

Are there other cases that raise stack level too deep exception, besides the classical program-execution-tree-is-too-deep scenario?

是的.由于堆栈不是以深度衡量,而是以字节为单位,因此存储在堆栈中的任何内容都会更快地填满它:

Yes. Since the stack is not measured in depth, but in bytes, anything stored on the stack will fill it up sooner:

def recurse(depth=0)
  recurse depth+1
rescue SystemStackError
  depth
end
=> nil
recurse
=> 8717

def recurse(depth=0)
  a,b,c = 1,2,3
  recurse depth+1
rescue SystemStackError
  depth
end
=> nil
recurse
=> 7264

def recurse(depth=0)
  a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z = *(0..25)
  recurse depth+1
rescue SystemStackError
  depth
end
=> nil
recurse
=> 3187

在这个例子中,一个只有一个变量的函数在失败之前可以进行数千次调用,而添加三个变量的作用很小;但是再添加 26 个变量会使堆栈大小膨胀到只有大约 3000 个级别可用的程度.

In this example, a function with only one variable can go several thousand calls deep before failing, and adding three more variables does very little; but adding 26 more variables balloons the stack size to a point where only around 3000 levels are available.

这当然在一定程度上取决于 ruby​​ 实现,以及它运行的系统.但我相信它会永远成为一般规则.

This will, of course depend somewhat on the ruby implementation, and the system it's running on. But I believe it will always hold as a general rule.

但是,我仍然认为递归可能是您的问题,因为在小调用链长度下发生这种情况所需的变量数量是巨大的.

However, I still think recursion is likely your problem, since the number of variables required to have this happen at small call chain lengths is immense.