177

我在尝试在 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 allocate vector of size 开头的错误消息表明无法获得内存,要么是因为大小超过了进程的地址空间限制,要么更可能是因为系统无法提供内存。请注意,在 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
4

9 回答 9

93

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

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

如果上述方法无法解决问题,请购买一台 64 位机器,尽可能多的 RAM,然后安装 64 位 R。

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

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

于 2011-03-02T22:34:15.687 回答
64

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

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

在此处输入图像描述

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

  • 准备特征,保存为 RData 文件,关闭 R,重新打开 R,然后加载训练特征。资源管理器通常显示较低的内存使用情况,这意味着即使 gc() 也无法恢复所有可能的内存,并且关闭/重新打开 R 最好从最大可用内存开始
  • 另一个技巧是只加载训练集进行训练(不要加载测试集,它通常是训练集大小的一半)。训练阶段可以最大限度地使用内存(100%),所以任何可用的东西都是有用的。当我正在试验 R 内存限制时,所有这些都是用一粒盐来完成的。
于 2014-07-15T09:35:33.257 回答
35

我访问了帮助页面,memory.limit发现在我的计算机上 R 默认最多可以使用 1.5 GB 的 RAM,并且用户可以增加这个限制。使用以下代码,

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

帮助我解决了我的问题。

于 2018-09-21T04:41:22.627 回答
15

以下是有关此主题的演示文稿,您可能会觉得有趣:

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

我自己没有尝试过讨论的东西,但这个bigmemory包似乎非常有用

于 2011-03-02T18:32:15.987 回答
12

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

于 2011-03-03T20:14:08.583 回答
12

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

于 2015-12-10T20:31:29.433 回答
8

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

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

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

于 2015-09-10T08:18:01.190 回答
3

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

例子:

gc()
memory.limit(9999999999)
fit <-lm(Y ~ X)
gc() 
于 2021-03-14T02:36:45.550 回答
2

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

# defrag memory 
save.image(file="temp.RData")
rm(list=ls())
load(file="temp.RData")
于 2018-02-26T00:48:11.513 回答