我正在使用一个列表,其中每个元素也是一个由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。)
编辑添加:我刚刚注意到,即使我覆盖列表本身(而不是创建新列表,我只是将操作的输出分配给旧列表),这个内存使用问题仍然存在。