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

Posted

技术标签:

【中文标题】R内存管理/无法分配大小为n Mb的向量【英文标题】:R memory management / cannot allocate vector of size n Mb 【发布时间】:2011-03-02 18:13:01 【问题描述】:

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

我了解这与获取连续内存块的困难有关(来自here):

错误信息开头不能 分配大小的向量表示一个 无法获得记忆,要么 因为尺寸超过了 进程的地址空间限制,或者, 更有可能,因为系统是 无法提供内存。笔记 在 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:什么是“免费”?一个 R 函数? @Manoel:在 R 中,释放内存的任务由垃圾收集器处理,而不是用户。如果在 C 级别工作,可以手动 CallocFree 内存,但我怀疑这不是 Benjamin 正在做的。 在 XML 库中您可以免费使用。从文档中:“这个通用函数可用于显式释放与给定对象关联的内存。它旨在用于外部指针对象,这些对象没有自动终结器函数/例程来清理由本机对象。” 【参考方案1】:

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

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

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

如果您无法做到这一点,则有许多用于远程计算的在线服务。

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

【讨论】:

任务是图像分类,随机森林。我需要有一个训练数据矩阵(最多 60 个波段)和从 20,000 到 6,000,000 行的任何地方,以提供给 randomForest。目前,我的最大行数约为 150,000 行,因为我需要一个连续的块来保存生成的 randomForest 对象......这也是 bigmemory 没有帮助的原因,因为 randomForest 需要一个矩阵对象。 “只在一个会话中创建你需要的对象”是什么意思? 只创建一次'a',如果你在第一次开始新会话时出错了 我要补充一点,对于包含大量计算但输出相对较小的大型循环的程序,通过 Rscript 调用循环的内部部分可能会更节省内存(来自 BASH 或 Python 脚本),然后在不同的脚本中整理/聚合结果。这样,每次迭代后内存都会完全释放。重新加载/重新计算传递给循环的变量会浪费一些计算,但至少您可以解决内存问题。【参考方案2】:

对于 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 内存限制时,这一切都是有道理的。

【讨论】:

R 自己进行垃圾收集,gc() 只是一种错觉。检查任务管理器只是非常基本的 Windows 操作。我唯一能同意的建议是以 .RData 格式保存 @DavidArenburg gc() 是错觉?这意味着我上面显示的内存使用量下降的图片是一种错觉。我认为你错了,但我可能错了。 我并不是说gc() 不起作用。我只是说 R 会自动完成,所以你不需要手动完成。见here @DavidArenburg 我可以告诉你一个事实,上图中的内存使用量下降是由于 gc() 命令。我不相信您指向的文档是正确的,至少对于我的设置不正确(Windows,R 版本 3.1.0 (2014-04-10) Platform: i386-w64-mingw32/i386 (32-bit) )。 好的,最后一次。 gc() 确实工作。你只是不需要使用它,因为 R 在内部完成它【参考方案3】:

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

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

帮我解决了我的问题。

【讨论】:

为什么会被否决?当然,这是一种危险的方法,但如果需要为会话分配更多内存以使其工作,它通常会有所帮助。 这只是一个windows特定的解决方案 哈哈。我需要memory.limit(size=7000)。顺便说一句,我正在使用 Windows 10 和 R x64。 @JeppeOlsen 为什么这是一种危险的方法?【参考方案4】:

以下是关于此主题的演示,您可能会感兴趣:

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

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

【讨论】:

有效,除非需要矩阵类(而不是 big.matrix)【参考方案5】:

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

【讨论】:

这不是一般的治疗方法——我已经切换,现在我有 Error: cannot allocate vector of size ... Gb 代替(但是是的,我有很多数据)。 也许不是治愈方法,但它有很大帮助。只需加载 RAM 并继续启动 memory.limit()。或者,也许考虑对数据进行分区/采样。 如果您在 64 位(本质上是无限的)中遇到问题,可能更多的是您试图分配一些非常庞大的东西。从理论上讲,您是否计算过向量应该有多大?否则,可能是您的计算机需要更多 RAM,但您只能拥有这么多。 很高兴在更多的正面对抗解决方案之前尝试这样的简单解决方案。谢谢。 此外,这不仅仅是 Windows 的问题。我目前在 Ubuntu 上运行,64 位 R,使用 Matrix,并且难以操作 20048 x 96448 Matrix 对象。【参考方案6】:

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

【讨论】:

【参考方案7】:

如果你是在 linux 环境下运行你的脚本,你可以使用这个命令:

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

并且服务器会为你分配所请求的内存(根据服务器的限制,但如果有好的服务器 - 可以使用大文件)

【讨论】:

我可以在 Amazon EC2 实例上使用它吗?如果是这样,我应该用什么代替server_name?我试图在 AMI 上做一个巨大的 Document-Term Matrix 时遇到了这个cannot allocate vector size...,我不知道为什么它没有足够的内存,或者我需要租多少。谢谢! 我是 Ubuntu 初学者,在上面使用 Rstudio。我有 16 GB 内存。我如何应用您在答案中显示的过程。谢谢【参考方案8】:

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

例子:

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

【讨论】:

非常感谢!使用这种方法,我能够计算出 21k+ 个位置的距离矩阵。生成的距离矩阵的大小为 3.5GB。 Windows 10、16GB、R 4.0.3、RStudio 1.3.1093 [应该很快更新] LOL 内存中的错误.limit(9999999999):别傻了!:您的机器有 4Gb 地址限制【参考方案9】:

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

# defrag memory 
save.image(file="temp.RData")
rm(list=ls())
load(file="temp.RData")

【讨论】:

以上是关于R内存管理/无法分配大小为n Mb的向量的主要内容,如果未能解决你的问题,请参考以下文章

09 管理内存对象

即使在 R 中使用磁盘框架后,也无法分配 10.3mb 的向量

分布式memcached学习——memcached内存管理机制

矢量的内存管理

是否可以增加 R 中的内存限制

内存管理相关API列表