用Rstudio跑程序的时候报错:

1
Error: protect(): protection stack overflow

大部分解决方案是在代码中设置options(expressions = 5e5),但不能解决。其实是在执行R代码是遇到防护堆叠上溢的error,但实际上服务器的内存很大,我们增加指针保护堆栈大小就行,但是要先把R程序准备成脚本,用Rscript运行的时候添加–max-ppsize选项。例如

1
2
3
Rscript --max-ppsize=500000 test.R

# The command-line option --max-ppsize controls the maximum size of the pointer protection stack. This defaults to 50000, but can be increased to allow deep recursion or large and complicated calculations to be done. Note that parts of the garbage collection process goes through the full reserved pointer protection stack and hence becomes slower when the size is increased. Currently the maximum value accepted is 500000.

顺便学习下R的内存控制,mark一下

使用命令行选项来控制R可用的内存

描述

使用命令行选项来控制R可用的内存。

用法

1
2
3
R --min-vsize=vl --max-vsize=vu --min-nsize=nl --max-nsize=nu --max-ppsize=N

mem.limits(nsize = NA,vsize = NA)

参数

说明
vl, vu, vsize Heap memory in bytes. 堆内存(以字节为单位)
nl, nu, nsize Number of cons cells.
N Number of nested PROTECT calls.

说明

R有一个可变大小的工作区,可以通过命令行的方式控制最小内存,但大多数用户可能不需要设置这些选项。但在运行大型任务时,这些设置变非常有用。

R 在单独的区域分别维护固定(fixed)和可变大小(variable sized)的对象。 其中第一个被分配为一个 cons cell数组(N cells,运行gc的时候可以看到),第二个被扔到heap上每个8字节的“V cells, vector cell”。 实际上,输入 vl 和 vu 向上舍入到下一个 8 的倍数。每个 cons cell在 R 的 32 位构建上占用 28 个字节,在 64 位构建上占用 56 个字节(即Ncell为28 bytes或56 bytes,Vcell为8 bytes)。

–*-nsize用于指定cons cell的数目,–*-vsize用于指定vector heap的字节大小。这两个选项后面需要跟整数和单位(G、M、K、k)

–min-*选项可以设置cons cell的数目和vector heap的最小值。R 将根据使用情况扩大或缩小,但不会超过 –max-* 选项设置的限制,也不会低于初始值。

vector heap的默认设置为6Mb,cons cell为350K(这些区域并未真实分配,而是出发垃圾回收的大小,garbage collection)。当R启动时,这些值可以通过命令行选项 –min-nsize 和 –min-vsize 设置(或者环境变量 R_NSIZE 和 R_VSIZE)。 此后,R 将根据使用情况扩大或缩小面积,但不会低于初始值。 最大vector heap可以设置环境变量 R_MAX_VSIZE改变。

R 在垃圾收集器中花费的时间将取决于两方面:

  • 这些初始设置
  • 内存管理器在内存填满时在垃圾回收以释放未使用的内存和增加这些区域之间做出的权衡

可以通过将环境变量 R_GC_MEM_GROW 设置为 0 到 3 之间的整数值来指定用于增长的策略。该变量在启动时会被读取, 较高的值会让heap增长更快,从而减少垃圾回收的时间,但会使用更多内存。

通过gc() 函数可以显示当前的内存消耗(heap 为数字 和 cons 单元格为兆字节)。object.size(a)可以显示R对象的大小。memory.profile() 用于分析 cons cell的使用情况。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
> gc() 
            used   (Mb) gc trigger   (Mb)  max used   (Mb)
Ncells  25267301 1349.5   68902915 3679.9  31438963 1679.1
Vcells 280693969 2141.6  436121022 3327.4 363367519 2772.3

> object.size(sample.annotation)
48976 bytes

> memory.profile()
Garbage collection 47 = 21+5+21 (level 2) ... 
1349.7 Mbytes of cons cells used (37%)
2141.6 Mbytes of vectors used (64%)
       NULL      symbol    pairlist     closure environment     promise 
          1       38255     1423758       27547        7886       33168 
   language     special     builtin        char     logical     integer 
     374489          45         692    22371123       41200      249764 
     double     complex   character         ...         any        list 
      23736          45      454412           9           0      113590 
 expression    bytecode externalptr     weakref         raw          S4 
          1       95870        7563        2156        2175        3986 

命令行选项 –max-ppsize 控制指针保护堆栈(pointer protection stack)的最大值。 默认值为 50000,但在深度递归和大型计算时可以调整,比如我这次遇到的问题。需要注意的是,部分垃圾回收过程会查看完整的堆栈,因此当大小增加时垃圾回收会变慢。–max-ppsize 目前接受的最大值是 500000。

参考:

https://astrostatistics.psu.edu/su07/R/html/base/html/Memory.html

https://stackoverflow.com/questions/32826906/how-to-solve-protection-stack-overflow-issue-in-r-studio

https://stat.ethz.ch/R-manual/R-devel/library/base/html/Memory.html

https://stat.ethz.ch/R-manual/R-devel/library/base/html/gc.html

####################################################################

#版权所有 转载请告知 版权归作者所有 如有侵权 一经发现 必将追究其法律责任

#Author: Jason

#####################################################################