在连接data.tables时如何防止R泄漏内存?

时间:2016-09-23 18:19:20

标签: r memory-management memory-leaks data.table rstudio-server

我正在使用一个列表,其中每个元素也是一个由R data.tables组成的列表。我的任务是获取每个子列表的 n 元素,然后将这些data.tables堆叠成更大的data.table。因此,从包含12个元素的20个列表的列表中,我最终得到12个元素的总列表,其中每个元素都是data.table

我没有使用代码来解决这个问题,但是我对这种情况下R内存管理的情况感到困惑。提取相对简单,就像这样(只是为了显示上下文,而不是自己的MWE):

lst_new <- lapply(X = list_indices,
                  FUN = function(idx) {return(rbindlist(l = lapply(X = lst_old,FUN = `[[`,idx)))})

我的问题是,为什么当我删除时,R不会释放最初分配给lst_old的内存?更一般地说,为什么我的rbind操作似乎在删除对象后保留在内存中?以下是一个最小的工作示例。

library(data.table)

# Create list elements of large enough size
uFunc_MakeElement <- function() {
    clicode <- paste(sample(x = c(letters,LETTERS),size = 4,replace = T),collapse = "")
    column_data <- replicate(n = 100,expr = {sample(x = c(0:20),size = 600000,replace = T)},simplify = FALSE)
    names(column_data) <- paste("var",1:100,sep = "")
    return(as.data.table(cbind(clicode = clicode,as.data.frame(column_data))))
}
lst_big <- replicate(n = 15,expr = uFunc_MakeElement(),simplify = FALSE)

# At this point, the rsession is consuming 4.01GB according to top (RES)
# According to RStudio, lst_big was 3.4Gb

# Transform to a data.table
dt_big <- rbindlist(l = lst_big)
# According to top, RES was 7.293Gb

rm(lst_big)
# RES does not change

dt_big <- rbind(dt_big,NULL)
# RES goes to 0.010t

gc()
# RES goes back down to 6.833Gb

我不确定为什么,在使用lst_big创建新data.table后删除rbindlist时,我没有将内存返回给我。即使在手动调用gc(您不应该这样做)之后,我仍然无法取回似乎分配给lst_big的内存。难道我做错了什么?有没有更好的方法来连接data.tables以便我不泄漏内存?

(用RStudio标记它,以防它有可能与IDE有关。这个例子来自在Ubuntu 14.04盒子上运行的RStudio Server。)

编辑添加:我刚刚注意到,即使我覆盖列表本身(而不是创建新列表,我只是将操作的输出分配给旧列表),这个内存使用问题仍然存在。

0 个答案:

没有答案