从data.table中调用fwrite函数时发生内存泄漏

问题描述

我的软件包中有一个顶级功能,该功能.csv文件的目录上执行各种数据清理任务。它读取.csv,将其转换为小写,将列转换为指定的类型,添加删除列,等等。

顶级功能如下:

top <- function(path,csv = FALSE,rds = FALSE) {  
  files <- get_file_or_dir(path) # returns a character vector of matching file(s)
  dirs <- parse_files(files) # Creates directories and moves files into them
  lapply(dirs,do_dir,csv,rds)
}

此呼叫:

do_dir <- function(dir,rds) {
   lapply(fs::dir_ls(dir),function(file) {
     conv_to_standard(file,rds)
  })
}

哪个调用

conv_to_standard <- function(file,rds) {

  df <- data.table::fread(file,sep = "\t",colClasses = character(),showProgress = FALSE)
  setup(df)
  conv_type_cols(df)
  conv_special_cols(df)
  conv_factor_cols(df)
  conv_order_cols(df)
  output(df,file,rds)
  return(NULL)
}

顶级参数csvrds是布尔值,指示生成.csv或.rds文件作为输出(或两者)。相关功能output函数

output <- function(df,rds) {
  output_csv(df,csv)
  output_rds(df,rds)
}

output_rds <- function(df,rds) {
  if(rds) {
    saveRDS(df,file = paste(tools::file_path_sans_ext(file),"_clean.rds",sep = ""))
  }
}

output_csv <- function(df,csv) {
  if(csv) {
    data.table::fwrite(df,"_clean.csv",sep = ""),showProgress = FALSE)
  }
}

当我在包含15个top("../test/")文件的目录中运行.csv时,我的函数完成了而没有内存分配问题,并且在任何给定时间仅使用1-2GB的RAM。但是,一旦设置了csv = TRUE,在处理了4-5个.csv文件之后,我最终会遇到内存分配错误和失败。您可以在下面看到第一种情况的个人资料:

without fwrite

当下面的csv = TRUE(仅调用调用fwrite函数)时,您会看到一种严重的内存分配错误,其中lapply循环中的内存永远不会出现释放。由于缺少分配的内存,最终导致我的函数失败:

with fwrite

最后两个示例之间的唯一区别是调用output_csv函数。有什么原因会导致分配内存失败?

fwrite是否打开我需要明确关闭文件连接?

更新: 经过大量的研究,我将问题缩小为一行代码

`%^%` <- function(lhs,rhs) {
    levels<-`(factor(stringi::stri_replace_all_fixed(lhs,"  "," ")),rhs)
}

当我将函数更改为此(执行相同的操作)时,问题完全消失了:

`%^%` <- function(lhs,rhs) {
  x <- factor(stringi::stri_replace_all_fixed(lhs," "))
  levels(x) <- rhs
  return(x)
}

这是一个非常奇怪的错误,我不知道为什么会发生。即使我不再遇到内存分配问题,我也很想听听有关发生这种情况的任何猜测。

R version 4.0.2 (2020-06-22)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19041)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)