R 无法在 ff 过程中分配内存。怎么会?

Posted

技术标签:

【中文标题】R 无法在 ff 过程中分配内存。怎么会?【英文标题】:R could not allocate memory on ff procedure. How come? 【发布时间】:2014-10-02 08:25:56 【问题描述】:

我正在使用带有 Intel Xeon 处理器和 24 GB RAM 的 64 位 Windows Server 2008 机器。我在尝试读取 11 GB(>2400 万行,20 列)的特定 TSV(制表符分隔)文件时遇到问题。我平时的伙伴read.table 让我失望了。我目前正在通过这个过程尝试包ff

> df <- read.delim.ffdf(file       = "data.tsv",
+                       header     = TRUE,
+                       VERBOSE    = TRUE,
+                       first.rows = 1e3,
+                       next.rows  = 1e6,
+                       na.strings = c("", NA),
+                       colClasses = c("NUMERO_PROCESSO" = "factor"))

这适用于大约 600 万条记录,但随后出现错误,如您所见:

read.table.ffdf 1..1000 (1000) csv-read=0.14sec ffdf-write=0.2sec
read.table.ffdf 1001..1001000 (1000000) csv-read=240.92sec ffdf-write=67.32sec
read.table.ffdf 1001001..2001000 (1000000) csv-read=179.15sec ffdf-write=94.13sec
read.table.ffdf 2001001..3001000 (1000000) csv-read=792.36sec ffdf-write=68.89sec
read.table.ffdf 3001001..4001000 (1000000) csv-read=192.57sec ffdf-write=83.26sec
read.table.ffdf 4001001..5001000 (1000000) csv-read=187.23sec ffdf-write=78.45sec
read.table.ffdf 5001001..6001000 (1000000) csv-read=193.91sec ffdf-write=94.01sec
read.table.ffdf 6001001..
Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  : 
  could not allocate memory (2048 Mb) in C function 'R_AllocStringBuffer'

如果我没记错的话,R 抱怨缺少内存来读取数据,但read...ffdf 程序不应该在读取数据时规避大量内存使用吗?我在这里做错了什么?

【问题讨论】:

在此线程中查看一些可能有帮助的答案:***.com/a/1820610/3897439。尤其是使用来自data.table 包和sqldf 包的fread。我知道您的问题不是时间效率,但也许其中一种方法也可以避免内存问题。 另外,如果您在更多代码中间读取此数据,这可能有助于确定您的内存使用情况:***.com/q/1358003/3897439 @Cotton.Rockwood:感谢您的帮助。不幸的是,fread 从未使用过我使用的数据框,因为它们总是包含一个充满嵌入式引号的字符列(函数帮助页面本身承认了这个问题)。至于您的链接直接指向的sqldf 替代方案,我似乎无法使其工作,因为显然它正在寻找逗号或分号作为分隔符,而我的文件使用制表符。 【参考方案1】:

(我意识到这是一个老问题,但我遇到了同样的问题并花了两天时间寻找解决方案。这似乎是记录我最终为后代找到的东西的好地方。)

问题不在于可用内存不足。问题是您已经达到了单个字符串的内存限制。来自帮助('内存限制'​​):

对单个对象也有限制。存储空间不能超过地址限制,如果您尝试超过该限制,错误消息开始无法分配长度向量。 字符串的字节数限制为2^31 - 1 ~ 2*10^9,这也是数组每个维度的限制。

在我的情况下(你的情况也是如此)我没有费心设置引号字符,因为我正在处理制表符分隔的数据并且我认为这并不重要。然而,在数据集中间的某个地方,我有一个带有不匹配引号的字符串,然后 read.table 愉快地跑到了行尾,一直到下一个,下一个,下一个......直到它达到了字符串大小的限制并爆炸了。

解决方案是在参数列表中显式设置quote = ""

【讨论】:

以上是关于R 无法在 ff 过程中分配内存。怎么会?的主要内容,如果未能解决你的问题,请参考以下文章

如果您在进程崩溃后在进程中分配内存会发生啥?

是否可以在linux中分配大量虚拟内存?

JAVA里String数组在内存分配中分配的空间每个占几个字节?

C语言申请内存?

如何在 Linux 中分配满足分页和缓存要求的内存?

java中创建数组时怎么分配内存?