【问题标题】:Workaround to R memory leak with XML package使用 XML 包解决 R 内存泄漏问题
【发布时间】:2014-06-30 19:31:01
【问题描述】:

我正在尝试运行一些简单的程序来从 html 代码中提取表格。但是,XML 包中的 readHTMLTable 似乎存在一些内存问题。有什么办法可以让我轻松解决这个问题。就像以某种方式为此命令指定一些特殊内存,然后手动释放它。

我试图把它放在一个函数中,并尝试使用 gc() 和不同版本的 R 和这个包,但似乎没有任何效果。我开始绝望了。

示例代码。如何在不爆炸内存大小的情况下运行它?

library(XML)
a = readLines("http://en.wikipedia.org/wiki/2014_FIFA_World_Cup")
while(TRUE) {
    b = readHTMLTable(a)
    #do something with b
}

编辑: 这样的事情仍然占据了我所有的记忆:

library(XML)
a = readLines("http://en.wikipedia.org/wiki/2014_FIFA_World_Cup")
f <- function(x) {
    b = readHTMLTable(x)
    rm(x)
    gc()
    return(b)
}

for(i in 1:100) {
    d = f(a)
    rm(d)
    gc()
}
rm(list=ls())
gc()

我使用的是 win 7 并尝试了 32 位和 64 位。

【问题讨论】:

  • 我在 Windows 上使用 XML 包时遇到了严重的内存问题。我的解决方案是定期重启 R(将数据保存到 CSV)。我给包作者发了电子邮件。我们交换了一些电子邮件,但他基本上说他不能/不会调试 Windows。
  • 好的。重新启动 R 工作,但每 5 分钟做一次手动工作并不是很好。我想唯一的方法是切换到 linux。 XML 是一个非常酷的包,但遗憾的是这些内存问题被破坏了。

标签: xml r memory-leaks web-scraping


【解决方案1】:

从Win7上的XML 3.98-1.4和R 3.1开始,使用free()函数可以完美解决这个问题。但它不适用于readHTMLTable()。以下代码完美运行。

library(XML)
a = readLines("http://en.wikipedia.org/wiki/2014_FIFA_World_Cup")
while(TRUE){
   b = xmlParse(paste(a, collapse = ""))
   #do something with b
   free(b)
}

xml2包也有类似问题,可以使用remove_xml()后跟gc()函数释放内存。

【讨论】:

  • 不能解决问题。如果您提取文档的任何部分,则整个对象将保留在内存中。你有一段时间(真)我有一个带有字符返回值的 lapply 提取原始文档的位。
【解决方案2】:

我在 XML 包中也遇到了很多内存泄漏问题(在 windows 和 linux 下),但我最终解决它的方法是在每个处理步骤结束时删除对象,即添加一个 rm( b) 和每次迭代结束时的 gc()。让我知道这是否也适合您。

【讨论】:

  • 在循环内部和循环之后都没有帮助。
  • 好吧,我所做的是将 XML 处理放在返回输出的 XMLproc 函数中,然后在我调用 XMLproc 的函数中添加 rm(out) 和 gc()。您能否检查一下这是否适合您?
  • 我没有得到这样的作品。我添加了一些我在原始问题中尝试过的内容。
  • 哈奇怪 - 我也在使用 windows 和 XML_3.98-1.1,你的第二段编辑的代码对我来说运行良好,没有任何内存泄漏......似乎这个 XML 包对于不幸的时刻......
  • 我正在运行相同版本的 XML 包。您是否从 Windows 任务管理器中检查了运行第二个代码后 R 占用了多少内存?最后一次 gc() 之后的统计信息不会显示“隐藏”消耗的内存,但是当我检查任务管理器时,它显示正在使用的内存约为 500mb。无论如何,感谢您的帮助。
【解决方案3】:

同样的问题,即使只是用doc &lt;- xmlParse(...); root &lt;- xmlRoot(doc) 读取文档,分配给doc 的内存永远不会释放到操作系统(在Windows 的任务管理器中监控)。

我们可能会尝试的一个疯狂想法是使用system("Rscript ...") 在单独的 R 会话中执行 XML 解析,将解析的 R 对象保存到文件中,然后我们在主 R 会话中读取该文件。哈克,但它至少可以确保任何内存被 XML 解析吞噬,在 Rscript 会话终止时释放并且不影响主进程!

【讨论】:

  • 很久以前我通过使用 Python 和 BeautifulSoup 解决了这个问题 :) 无论如何,感谢您的帮助。我会尽快尝试您的解决方案。
  • 另请参阅我在 stackoverflow.com/questions/23696391/… 上提出的答案,重新使用新的 xml2 库(我也将它作为这个问题的答案发布,但有人删除了它)。
  • 这个解决方案今天对我有用。它效率不高,但它让我可以在数千个文件上使用我的旧系统。
猜你喜欢
  • 2012-08-19
  • 2010-12-11
  • 2012-05-23
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多