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

时间:2013-02-06 00:09:40

标签: r

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

  

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

CStack_info()的输出是:

Cstack_info()
    size    current  direction eval_depth 
67108864       8120          1          2 

我的机器上有足够的内存,我只想弄清楚如何增加CS的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)
}

14 个答案:

答案 0 :(得分:47)

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

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

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

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

要对此设置进行永久性调整,请将ulimit命令添加到您的shell启动文件中,以便每次登录时执行该命令。我无法提供比那,因为它取决于你具有哪些外壳和东西。我也不知道如何登录图形环境(如果您没有在终端窗口中运行R,这将是相关的。)

答案 1 :(得分:16)

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

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

答案 2 :(得分:8)

这种情况发生在我身上是出于完全不同的原因。我在组合两列时不小心创建了一个超长字符串:

output_table_subset = mutate(big_data_frame,
     combined_table = paste0(first_part, second_part, col = "_"))

而不是

output_table_subset = mutate(big_data_frame,
     combined_table = paste0(first_part, second_part, sep = "_"))

让我永远想弄清楚,因为我从未预料到粘贴会导致问题。

答案 3 :(得分:3)

我遇到了接收&#34; C堆栈使用率太接近极限的问题&#34;错误(虽然对于另一个应用程序而不是上面user2045093所述的应用程序)。我尝试了zwol的建议,但它没有成功。

令我惊讶的是,我可以通过安装最新版本的R for OS X(目前版本为3.2.3)以及最新版本的R Studio for OS X(目前:0.99.840)来解决问题因为我正在使用R Studio。

希望这也可能对你有所帮助。

答案 4 :(得分:2)

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

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")
  

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

这些函数将继续递归地相互调用,并且理论上将永远不会完成。只有系统内的检查才能阻止这种情况的发生,并避免占用计算机的所有计算资源。您需要更改功能以确保它们不会递归调用自己(或彼此调用)。

答案 5 :(得分:1)

One issue here can be that you're calling f inside itself

plop <- function(a = 2){
  pouet <- sample(a)
  plop(pouet)
}
plop()
Erreur : évaluations trop profondément imbriquées : récursion infinie / options(expressions=) ?
Erreur pendant l'emballage (wrapup) : évaluations trop profondément imbriquées : récursion infinie / options(expressions=) ?

答案 6 :(得分:0)

正如马丁摩根写的那样......问题是你在递归中得到了太深的内心。如果递归根本没有收敛,你需要自己打破它。我希望这段代码能够正常运行,因为它没有经过测试。但至少应该明确这一点。

f <- function(root=1,lambda=1,depth=1) {
 if(depth > 256){
  return(NA)
 }
 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,depth+1);
   }
   if(child[2] == 1 && child[1] == 0) {
     child[2] <- f(root=child[2],lambda,depth+1);
   }
  }
  if(child[1] == NA | child[2] == NA){
   return NA;
  }
  if(child[1] == 0 && child[2] == 0) {
    break;
  }
  if(child[1] == 1 || child[2] == 1) {
    root <- sample(x,1,replace=TRUE,prob);
  }
 }
 return(root)
}

答案 7 :(得分:0)

引起相同问题的另一种方法:

library(debug)
mtrace(lapply)

在这里递归调用不太明显。

答案 8 :(得分:0)

如果您使用plot_ly,请检查要传递的列。似乎对于POSIXdt / ct列,您必须在传递给plotly之前使用as.character(),否则会收到此异常!

答案 9 :(得分:0)

对于所有人的信息,我突然在Windows 7(64位)上的R 3.6.1中遇到了这个问题。以前这不是问题,现在当我尝试“保存(。)”数据甚至执行“ save.image(。)”时,堆栈限制似乎随处可见。就像序列化将这些堆栈吹走了。

我正在认真考虑回落到3.6.0。在那里没有发生。

答案 10 :(得分:0)

我的情况也许是一个更独特的案例,但可能会帮助有这个确切问题的少数人:

我的情况绝对与空间使用无关,R仍然给出了:
C stack usage is too close to the limit

我有一个已定义的功能,它是基本功能的升级:

  

saveRDS()

但是,
偶然地,此定义的函数称为saveRDS()而不是safe_saveRDS()
因此,超过该定义后,当代码到达wihch行时实际上使用saveRDS(...)(它调用原始基本版本,而不是升级版本)时,它给出了以上错误并被破坏了。

因此,如果在调用某些保存功能时遇到该错误,请查看是否没有意外地对其进行处理。

答案 11 :(得分:0)

我经常在R脚本的顶部添加注释掉的source("path/to/file/thefile.R")行,例如thefile.R,因此我可以轻松地将其复制粘贴到终端中以运行它。如果忘记注释掉该行,则会出现此错误,因为运行文件会运行文件,文件会运行文件,文件会运行...

如果是原因,解决方案很简单:注释掉这一行。

答案 12 :(得分:0)

不确定我们是否要在此处列出问题,但是leaflet()发生在我身上。 我正在尝试映射其中date列属于类POSIXlt的数据框。 改回POSIXct解决了这个问题。

答案 13 :(得分:0)

在Linux上,我这样做是永久性地增加了堆栈和内存锁的大小:

      * -- line 1 --
     * -- line 2 --
° -- line 3 --
    ' -- line 4 --
        ° -- line 5 --

然后,在文件末尾添加以下行。

sudo vi /etc/security/limits.conf