错误:C堆栈使用率太接近极限

use*_*093 72 r

我试图在R中运行一些相当深的递归代码,它不断给我这个错误:

错误:C堆栈使用率太接近极限

我的输出CStack_info()是:

Cstack_info()
    size    current  direction eval_depth 
67108864       8120          1          2 
Run Code Online (Sandbox Code Playgroud)

我的机器上有足够的内存,我只想弄清楚如何增加R的CStack.

编辑:有人要求一个可重复的例子.这是导致问题的一些基本示例代码.运行f(1,1)几次就会出现错误.请注意,我已经设置了--max-ppsize = 500000和options(表达式= 500000),所以如果你没有设置它们,你可能会得到关于这两件事之一的错误.正如你所看到的,递归可以在这里非常深入,我不知道如何让它一致地工作.谢谢.

f <- function(root=1,lambda=1) {
    x <- c(0,1);
    prob <- c(1/(lambda+1),lambda/(lambda+1));
        repeat {
      if(root == 0) {
        break;
      }
      else {
        child <- sample(x,2,replace=TRUE,prob);
        if(child[1] == 0 && child[2] == 0) {
          break;
        }
        if(child[1] == 1) {
          child[1] <- f(root=child[1],lambda);
        }
        if(child[2] == 1 && child[1] == 0) {
          child[2] <- f(root=child[2],lambda);
        }
      }
      if(child[1] == 0 && child[2] == 0) {
        break;
      }
      if(child[1] == 1 || child[2] == 1) {
        root <- sample(x,1,replace=TRUE,prob);
      }
        }
    return(root)
}
Run Code Online (Sandbox Code Playgroud)

zwo*_*wol 50

堆栈大小是一个操作系统参数,可按进程调整(请参阅参考资料setrlimit(2)).据我所知,您无法在R内调整它,但您可以在启动R之前使用ulimit命令从shell调整它.它的工作原理如下:

$ ulimit -s # print default
8192
$ R --slave -e 'Cstack_info()["size"]'
   size 
8388608
Run Code Online (Sandbox Code Playgroud)

8388608 = 1024*8192; R打印的值相同ulimit -s,但以字节为单位而不是千字节.

$ ulimit -s 16384 # enlarge stack limit to 16 megs
$ R --slave -e 'Cstack_info()["size"]'
    size 
16777216 
Run Code Online (Sandbox Code Playgroud)

  • ...或者只是将其设置为"无限制". (11认同)
  • [`RAppArmor` 包](https://cran.r-project.org/web/packages/RAppArmor/index.html) 提供了一个`setr​​limit(2)` 的接口。此功能可能会在某个时候在 `ulimit` 包中可用。 (2认同)
  • ** RAppArmor **包中不再存在此函数。有什么想法吗? (2认同)
  • Windows 的修复程序是什么? (2认同)
  • 更改限制不会解决此问题。递归函数将继续运行,直到达到上限。 (2认同)

Mar*_*gan 19

我怀疑,无论堆栈限制如何,你最终都会得到太深的递归.例如,使用lambda = Inf,f(1)会无限期地导致立即递归.递归的深度似乎是随机游走,有一些概率r更深,1-r完成当前递归.当你达到堆栈限制时,你已经做了很多"更深层次"的步骤.这意味着r> 1/2,并且绝大多数时间你只会继续递归.

而且,即使在无限递归的情况下,似乎几乎可以推导出解析或至少数值解.可以将p定义为f(1)== 1的概率,在单次迭代后写入"子"状态的隐式表达式,并将它们与p等同,并求解.然后,p可以用作从二项分布中单次绘制成功的机会.

  • 这实际上是隐藏的正确答案 - 确保你没有那么深的回避...... (2认同)

Ale*_*eph 8

这种情况发生在我身上的原因完全不同.我在组合两列时偶然创建了一个超长字符串:

output_table_subset = mutate(big_data_frame,
     combined_table = paste0(first_part, second_part, col = "_"))
Run Code Online (Sandbox Code Playgroud)

代替

output_table_subset = mutate(big_data_frame,
     combined_table = paste0(first_part, second_part, sep = "_"))
Run Code Online (Sandbox Code Playgroud)

让我永远想弄清楚,因为我从来没有想到粘贴会导致问题.


DAW*_*DAW 5

我遇到了同样的问题,即收到“C 堆栈使用率太接近限制”错误(尽管是针对另一个应用程序而不是上面 user2045093 所述的应用程序)。我尝试了 zwol 的建议,但没有成功。

令我惊讶的是,我可以通过为 OS X 安装最新版本的 R(当前:版本 3.2.3)以及用于 OS X 的最新版本的 R Studio(当前:0.99.840)来解决这个问题,因为我我正在与 R Studio 合作。

希望这也可以对您有所帮助。

  • 我切换到更高版本的 R。它工作过一次,但错误再次出现并且现在是一致的。帮助! (2认同)

Tom*_*lly 5

此错误不是由于内存,而是由于递归。函数正在调用自身。为了说明这一点,这是两个相互调用的函数的最小示例:

change_to_factor <- function(x){
  x <- change_to_character(x)
  as.factor(x)
} 

change_to_character <- function(x){
  x <- change_to_factor(x)
  as.character(x)
}

change_to_character("1")
Run Code Online (Sandbox Code Playgroud)

错误:C堆栈使用量7971600太接近限制

这些函数将继续递归调用,理论上将永远不会完成。只有系统内的检查才能防止这种情况无限期地发生并消耗计算机的所有计算资源。您需要更改函数以确保它们不会递归调用自身(或彼此调用)。

  • 拒绝递归缩小了计算机解决问题的范围。我最好建议在每个递归调用的函数中使用所谓的终止符。终止符的作用是有条件地停止进一步的递归调用,最好的方法是计算递归的深度,并在达到给定限制时立即停止(在系统错误发生之前)。 (2认同)