在可用内存充足的情况下,无法在R中分配向量

13

我试图使用data.table包在64位的R上加载一个大型CSV文件(226M行,38列)。该文件在磁盘上的大小约为27Gb。我在一台具有64GB RAM的服务器上执行此操作。我关闭了几乎所有其他内容,并开始了一个全新的R/Rstudio会话,因此当我启动fread时,只使用了2GB的内存。随着读取过程进行,我看到内存使用量上升到约45.6 Gb,然后我遇到了可怕的Error: cannot allocate vector of size 1.7 Gb。然而,仍然剩下超过18Gb可用。是否可能在18Gb的RAM中没有1.7Gb的连续块?这是否与已提交的大小有关(我承认我没有完全理解),如果是这样,是否有任何方法可以将提交的大小最小化以便留出足够的空间?

该列表包括我想要随时间汇总和总结某些统计数据的用户群体的历史记录。使用fread中的select,我已经能够导入38列中的子集,因此我不至于完全失误,但这意味着如果我需要处理其他变量,我就需要挑选,可能最终会遇到相同的错误。

对于我拥有的设置,是否有其他方法可以将整个数据集加载到内存中,还是我只需要继续导入子集或转移到大数据友好型平台?

谢谢您。

读取前的内存使用情况

Memory usage prior to read

失败时的内存使用情况

Memory usage at failure

会话信息

R version 3.3.0 Patched (2016-05-11 r70599)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows Server >= 2012 x64 (build 9200)

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

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] data.table_1.9.6

loaded via a namespace (and not attached):
[1] tools_3.3.0  chron_2.3-47

你可以看一下 iotools 包,它有一些功能可能对这种情况有所帮助。 - lmo
1
首先检查 memory.limit() 来查看R实际可用的内存有多少。 - Psidom
1
@Psidom,我做了,它是完整的64GB。谢谢。 - Avraham
6
从那个解释"committed size"的链接来看,似乎你仅仅是用完了实际的内存(已经被分配给R,但尚未填充实际位)。考虑到你的27Gb文件会扩展到更大的大小 - 我猜想你在其中有很多小整数?一个技巧是将这些列读入为字符串,然后只在必要时将它们转换为整数进行任何操作。 - eddi
@eddi 你可能是对的。虽然它很简单,请将您的评论发布为答案,以便我可以给您信用 :)。 - Avraham
显示剩余2条评论
1个回答

5

由于某些类型的数据在纯文本中使用的内存比在内存中要少,因此您会面临内存不足的问题(反之亦然)。 其经典示例是单个数字整数(0-9),它们仅占用文本文件中的一个字节,但在R中将使用4个字节的内存(反之,与4位数字相对应的文本字符所占用的内存较小)。

解决此问题的一种方法是将这些列读取为 character,这将保持内存占用量相同,并且只有在对它们进行数值操作时才将它们转换为整数。 当然,这样做的权衡将是速度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接