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


149

我在尝试在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

我了解这与获取连续内存块(从此处)的难度有关:

开头的错误消息无法分配大小向量,表明获取内存失败,原因是大小超出了进程的地址空间限制,或者更有可能是因为系统无法提供内存。请注意,在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

尝试使用“ free”来释放未使用的其他进程的内存。
Manoel Galdino

5
// @ Manoel Galdino:什么是“免费”?R功能?
本杰明

3
@Manoel:在R中,释放内存的任务是由垃圾收集器而不是用户处理的。如果在C级的工作,一个可以手动CallocFree记忆,但我怀疑这是不是本杰明在做什么。
Sharpie

您可以在XML库中免费使用。从文档中:“该通用函数可用于显式释放与给定对象关联的内存。它旨在用于没有自动终结函数/例程的外部指针对象,该函数/例程可以清除由对象使用的内存。本机对象。”
Manoel Galdino

Answers:


78

考虑您是否确实确实需要所有这些数据,还是矩阵可以稀疏?R中Matrix对稀疏矩阵有很好的支持(例如,参见软件包)。

当需要制作这种大小的对象时,请将R中的所有其他进程和对象减到最少。使用gc()清除目前未使用的内存,或者更好的只是你创建一个会话需要的对象

如果以上方法无济于事,请获取一台具有尽可能多RAM的64位计算机,然后安装64位R。

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

如果您不能做到这一点,那么像包ff(或bigmemorySascha提到的)这样的内存映射工具将帮助您构建新的解决方案。以我有限的经验,ff是更高级的软件包,但是您应该阅读High Performance Computing有关CRAN任务视图的主题。


1
任务是使用randomForest对图像进行分类。我需要一个训练数据矩阵(最多60个波段),以及20,000至6,000,000行中的任意行,以馈送到randomForest。目前,我最多可以容纳约15万行,因为我需要一个连续的块来保存生成的randomForest对象...这也是为什么bigmemory不能提供帮助的原因,因为randomForest需要一个矩阵对象。
本杰明

“仅在一个会话中创建所需的对象”是什么意思?
本杰明

只创建一次“ a”,如果您在第一次启动时弄错的话,则开始新的会话
mdsumner 2011年

1
我要补充一点,对于包含大型循环的程序,其中需要进行大量的计算但输出相对较小,通过Rscript(从BASH或Python脚本)调用循环的内部部分可能会更节省内存。 ,然后在不同的脚本中整理/汇总结果。这样,每次迭代后就完全释放了内存。重新加载/重新计算传递给循环的变量会浪费一些计算资源,但至少您可以解决内存问题。
本杰明

54

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

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

在此处输入图片说明

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

  • 准备特征,另存为RData文件,关闭R,重新打开R,并加载火车特征。资源管理器通常显示较低的内存使用率,这意味着即使gc()也无法恢复所有可能的内存,并且关闭/重新打开R最好以最大的可用内存开始
  • 另一个技巧是仅加载训练用的训练集(不加载测试集,通常可能是训练集大小的一半)。训练阶段可以最大程度地使用内存(100%),因此可用的任何东西都是有用的。我正在尝试使用R内存限制时,所有这些都需要花一点盐。

9
R自己进行垃圾收集,gc()只是一种幻想。检查任务管理器只是非常基本的Windows操作。我唯一同意的建议是以.RData格式保存
David Arenburg 2014年

3
@DavidArenburg gc()是一种幻想?那意味着我上面显示内存使用下降的图片是一种幻想。我认为您错了,但我可能会误会。
蒂莫西·亨利

4
我并不是说那gc()行不通。我只是说R会自动执行,因此您不需要手动执行。看到这里
David Arenburg 2014年

2
@DavidArenburg我可以告诉您一个事实,即上图中的内存使用量下降是由于gc()命令引起的。我认为您指向的文档不正确,至少对于我的设置而言不正确(Windows,R版本3.1.0(2014-04-10)平台:i386-w64-mingw32 / i386(32位))。
蒂莫西·亨利

15
好的,最后一次。gc() 确实有效。您只是不需要使用它,因为R在内部使用它
David Arenburg 2014年


14

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


25
一般而言,这不是治愈方法-我已经换了,Error: cannot allocate vector of size ... Gb但现在我有了(但是,我有很多数据)。
om-nom-nom 2012年

2
也许不是治愈方法,但有很大帮助。只需加载RAM并继续提高memory.limit()。或者,也许考虑对数据进行分区/采样。
random_forest_fanatic

如果您甚至在64位(基本上是无限的)上也遇到了麻烦,那么尝试分配真正大量的内容可能更多。从理论上讲,您是否已经计算出向量的大小?否则,可能是您的计算机需要更多的RAM,但您只能拥有太多内存。
hangmanwa7id 2015年

很高兴先尝试像这样的简单解决方案,然后再面对更多难题。谢谢。
新星

而且,这不是Windows专有的问题。我目前正在使用Matrix在64位R的Ubuntu上运行,并且难以操纵20048 x 96448 Matrix对象。

12

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


11

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

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

帮助我解决了我的问题。


1
为什么这被否决?当然,这是一种危险的方法,但是如果仅需要为会话分配更多的内存以使其正常工作,它通常会有所帮助。
杰普·奥尔森

3
这只是Windows的特定解决方案
Jinhua Wang

9

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

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

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


1
我可以在Amazon EC2实例上使用它吗?如果是这样,我该怎么代替server_name?我cannot allocate vector size...试图在AMI上创建一个庞大的文档术语矩阵时遇到了这种情况,但我不知道为什么它没有足够的内存,或者我需要租用多少内存。谢谢!
seth127 '16

我是Ubuntu初学者,并且在其上使用Rstudio。我有16 GB RAM。我如何应用答案中显示的过程。谢谢
runjumpfly

3

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

# defrag memory 
save.image(file="temp.RData")
rm(list=ls())
load(file="temp.RData")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.