R 内存管理 / 无法分配大小为 n Mb 的向量

R memory management / cannot allocate vector of size n Mb

提问人:Benjamin 提问时间:3/3/2011 最后编辑:Gregor ThomasBenjamin 更新时间:3/14/2021 访问量:652932

问:

我在尝试在 R 中使用大型对象时遇到了问题。例如:

> memory.limit(4000)
> a = matrix(NA, 1500000, 60)
> a = matrix(NA, 2500000, 60)
> a = matrix(NA, 3500000, 60)
Error: cannot allocate vector of size 801.1 Mb
> a = matrix(NA, 2500000, 60)
Error: cannot allocate vector of size 572.2 Mb # Can't go smaller anymore
> rm(list=ls(all=TRUE))
> a = matrix(NA, 3500000, 60) # Now it works
> b = matrix(NA, 3500000, 60)
Error: cannot allocate vector of size 801.1 Mb # But that is all there is room for

我知道这与获得连续内存块的困难有关(从这里):

错误消息开头 cannot 分配大小的向量表示 无法获取内存,或者 因为大小超出了 进程的地址空间限制,或者 更有可能,因为该系统是 无法提供内存。注意 在 32 位构建中,很可能有 有足够的可用内存,但 没有足够大的连续块 要将其映射到的地址空间。

我怎样才能解决这个问题?我的主要困难是我在脚本中到达某个点,而 R 无法为对象分配 200-300 Mb......我无法真正预先分配块,因为我需要内存进行其他处理。即使我小心翼翼地删除不需要的对象,也会发生这种情况。

编辑:是的,对不起:Windows XP SP3,4Gb RAM,R 2.12.0:

> sessionInfo()
R version 2.12.0 (2010-10-15)
Platform: i386-pc-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=English_Caribbean.1252  LC_CTYPE=English_Caribbean.1252   
[3] LC_MONETARY=English_Caribbean.1252 LC_NUMERIC=C                      
[5] LC_TIME=English_Caribbean.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base
矩阵 向量 存储器 - 管理 R-FAQ

评论

0赞 Manoel Galdino 3/3/2011
尝试使用“free”来分配其他未使用的进程的内存。
5赞 Benjamin 3/3/2011
@Manoel Galdino:什么是“免费”?R 函数?
5赞 Sharpie 3/3/2011
@Manoel:在 R 中,释放内存的任务由垃圾回收器处理,而不是由用户处理。如果在 C 级别工作,可以手动和内存,但我怀疑这不是 Benjamin 正在做的事情。CallocFree
0赞 Manoel Galdino 3/3/2011
在库 XML 中,您可以免费使用。来自文档:“此泛型函数可用于显式释放与给定对象关联的内存。它旨在用于外部指针对象,这些对象没有自动终结器函数/例程来清理本机对象使用的内存。

答:

16赞 Sacha Epskamp 3/3/2011 #1

以下是您可能会感兴趣的有关此主题的演示文稿:

http://www.bytemining.com/2010/08/taking-r-to-the-limit-part-ii-large-datasets-in-r/

我自己没有尝试过讨论的内容,但该软件包似乎非常有用bigmemory

评论

4赞 Benjamin 3/3/2011
有效,除非需要矩阵类(而不是 big.matrix)
104赞 mdsumner 3/3/2011 #2

考虑一下你是否真的需要显式地需要所有这些数据,或者矩阵可以是稀疏的?R 中有很好的支持(例如,请参阅包)对稀疏矩阵的支持。Matrix

当需要创建此大小的对象时,将 R 中的所有其他进程和对象保持在最低限度。用于清除现在未使用的内存,或者最好只在一个会话中创建所需的对象gc()

如果上述方法都无济于事,请购买一台 64 位计算机,并尽可能多地安装 RAM,然后安装 64 位 R。

如果您不能做到这一点,那么有许多用于远程计算的在线服务。

如果你做不到这一点,内存映射工具,如package(或Sascha提到的)将帮助你构建一个新的解决方案。在我有限的经验中,是更高级的软件包,但您应该阅读有关 CRAN 任务视图的主题。ffbigmemoryffHigh Performance Computing

评论

1赞 Benjamin 3/3/2011
任务是使用 randomForest 进行图像分类。我需要有一个训练数据矩阵(最多 60 个波段)和 20,000 到 6,000,000 行之间的任意位置才能提供给 randomForest。目前,我的最大值约为 150,000 行,因为我需要一个连续的块来保存生成的 randomForest 对象......这也是为什么 bigmemory 没有帮助的原因,因为 randomForest 需要一个矩阵对象。
0赞 Benjamin 3/3/2011
“仅在一个会话中创建您需要的对象”是什么意思?
0赞 mdsumner 3/7/2011
只创建“a”一次,如果你第一次开始一个新会话时弄错了
1赞 Benjamin 3/5/2016
我要补充一点,对于包含大型循环的程序,其中进行了大量计算但输出相对较小,通过 Rscript(从 BASH 或 Python 脚本)调用循环的内部部分可能会更节省内存,然后整理/聚合结果在不同的脚本中。这样,每次迭代后都会完全释放内存。重新加载/重新计算传递给循环的变量会浪费一些计算,但至少您可以解决内存问题。
12赞 David Heffernan 3/4/2011 #3

规避此限制的最简单方法是切换到 64 位 R。

评论

32赞 om-nom-nom 4/12/2012
一般来说,这不是治愈方法——我已经转换了,现在我有了(但是的,我有很多数据)。Error: cannot allocate vector of size ... Gb
2赞 random_forest_fanatic 7/30/2013
也许不能治愈,但它有很大帮助。只需加载 RAM 并继续启动 memory.limit()。或者,可以考虑对数据进行分区/采样。
0赞 hangmanwa7id 2/21/2015
如果你在 64 位(基本上是无限的)中也遇到了问题,那么可能更多的是你试图分配一些非常庞大的东西。从理论上讲,你有没有计算过向量应该有多大?否则,您的计算机可能需要更多的 RAM,但您只能拥有这么多。
0赞 Nova 3/8/2017
很高兴在更多正面对墙的解决方案之前尝试这样的简单解决方案。谢谢。
0赞 5/22/2018
此外,这不仅仅是 Windows 的问题。我目前在 Ubuntu 上运行,64 位 R,使用 Matrix,并且在操作 20048 x 96448 Matrix 对象时遇到困难。
69赞 Timothée HENRY 7/15/2014 #4

对于 Windows 用户,以下内容帮助我了解了一些内存限制:

  • 在打开 R 之前,打开 Windows 资源监视器(Ctrl-Alt-Delete / 启动任务管理器 / 性能选项卡 / 单击底部按钮“资源监视器”/内存选项卡)
  • 您将看到在打开 R 之前我们已经使用了多少 RAM 内存,以及由哪些应用程序使用。就我而言,使用了总共 1.6GB 中的 4 GB。所以我只能为 R 获得 2.4 GB,但现在更糟了......
  • 打开 R 并创建一个 1.5 GB 的数据集,然后将其大小减小到 0.5 GB,资源监视器显示我的 RAM 使用率接近 95%。
  • 使用 gc() 进行垃圾回收 => 它有效,我可以看到内存使用量下降到 2 GB

enter image description here

适用于我的机器的其他建议:

  • 准备功能,另存为 RData 文件,关闭 R,重新打开 R,然后加载训练功能。资源管理器通常显示较低的内存使用率,这意味着即使 gc() 也无法恢复所有可能的内存,关闭/重新打开 R 最适合从最大可用内存开始
  • 另一个技巧是只加载用于训练的训练集(不要加载测试集,测试集的大小通常只有训练集的一半)。训练阶段可以最大限度地使用内存 (100%),因此任何可用的东西都是有用的。所有这些都是一粒盐,因为我正在试验 R 内存限制。

评论

18赞 David Arenburg 7/15/2014
R 本身做垃圾回收,只是一种错觉。检查任务管理器只是非常基本的 Windows 操作。我唯一能同意的建议是存钱。RData 格式gc()
6赞 Timothée HENRY 7/15/2014
@DavidArenburg gc() 是一种错觉?这意味着我上面显示内存使用率下降的图片是一种错觉。我认为你错了,但我可能错了。
7赞 David Arenburg 7/15/2014
我不是说那行不通。我只是说 R 会自动完成,因此您不需要手动执行。看这里gc()
4赞 Timothée HENRY 7/15/2014
@DavidArenburg我可以告诉你一个事实,上图中内存使用率的下降是由于 gc() 命令造成的。我不相信你指出的文档是正确的,至少不适合我的设置(Windows,R 版本 3.1.0 (2014-04-10) 平台:i386-w64-mingw32/i386(32 位))。
21赞 David Arenburg 7/15/2014
好的,最后一次。 确实有效。你只是不需要使用它,因为 R 在内部执行它gc()
9赞 nurit 9/10/2015 #5

如果您在 linux 环境中运行脚本,则可以使用以下命令:

bsub -q server_name -R "rusage[mem=requested_memory]" "Rscript script_name.R"

服务器将为您分配请求的内存(根据服务器限制,但使用良好的服务器 - 可以使用 hugefiles)

评论

1赞 seth127 3/15/2016
我可以在 Amazon EC2 实例上使用它吗?如果是这样,我应该用什么来代替?我试图在 AMI 上做一个巨大的文档术语矩阵时遇到了这个问题,但我无法弄清楚为什么它没有足够的内存,或者我需要租用多少内存。谢谢!server_namecannot allocate vector size...
0赞 runjumpfly 10/21/2016
我是 Ubuntu 初学者,在上面使用 Rstudio。我有 16 GB RAM。我如何应用您在答案中显示的过程。谢谢
12赞 Kwaku Damoah 12/11/2015 #6

我遇到了类似的问题,我使用了 2 个闪存驱动器作为“ReadyBoost”。这两个驱动器提供了额外的 8GB 内存提升(用于缓存),它解决了问题,也提高了整个系统的速度。 要使用 Readyboost,请右键单击驱动器,转到属性并选择“ReadyBoost”,然后选择“使用此设备”单选按钮,然后单击“应用”或“确定”进行配置。

3赞 Simon Woodward 2/26/2018 #7

上面提到的保存/加载方法对我有用。我不确定如何/是否对内存进行碎片整理,但这似乎有效。gc()

# defrag memory 
save.image(file="temp.RData")
rm(list=ls())
load(file="temp.RData")
44赞 Rajib Kumar De 9/21/2018 #8

我关注到帮助页面,发现在我的计算机上,默认情况下 R 最多可以使用 ~ 1.5 GB 的 RAM,并且用户可以增加此限制。使用以下代码,memory.limit

>memory.limit()
[1] 1535.875
> memory.limit(size=1800)

帮助我解决了我的问题。

评论

5赞 Jeppe Olsen 1/10/2019
为什么这被否决了?当然,这是一种危险的方法,但如果只需要为会话分配更多的内存即可使其正常工作,它通常会有所帮助。
6赞 Jinhua Wang 1/16/2020
这只是特定于 Windows 的解决方案
0赞 Nip 9/29/2020
哈哈。我需要.顺便说一句,我正在使用 Windows 10 和 R x64。memory.limit(size=7000)
6赞 melbez 10/7/2020
@JeppeOlsen 为什么这是一种危险的方法?
0赞 Jeppe Olsen 6/3/2022
@melbez'因为它会使您的计算机崩溃。
4赞 Jalles10 3/14/2021 #9

一种选择是在运行命令之前和之后,通过运行命令来执行“垃圾回收”,这将导致高内存消耗,除了使用命令外,这将为您的分析释放内存。gc()memory.limit()

例:

gc()
memory.limit(9999999999)
fit <-lm(Y ~ X)
gc() 

评论

2赞 mjaniec 5/15/2021
多谢!使用这种方法,我能够计算 21k+ 位置的距离矩阵。生成的距离矩阵的大小为 3.5GB。Windows 10、16GB、R 4.0.3、RStudio 1.3.1093 [应尽快更新]
0赞 cs0815 12/10/2021
memory.limit(9999999999) 中的 LOL 错误:不要傻!:您的机器有 4Gb 地址限制
1赞 Rui Barradas 5/28/2023
R 4.3 在这里。.memory.limit(9999999999) [1] Inf Warning message: 'memory.limit()' is no longer supported