有没有办法在R中进行并行计算时释放内存

Zih*_*Guo 8 parallel-processing memory-management r

假设我想使用多个核运行R程序,如下所示

library(foreach)
library(doParallel)

no_cores <- detectCores() - 2

cl<-makeCluster(no_cores, outfile = "debug.txt")

registerDoParallel(cl)

result <- foreach(i = 10:100, 
        .combine = list,
        .multicombine = TRUE)  %dopar%  {

          set.seed(i)

          a <- replicate(i, rnorm(20)) 
          b <- replicate(i, rnorm(20))

          list(x = a + b, y = a - b)

        } 
Run Code Online (Sandbox Code Playgroud)

但是,我发现程序运行一段时间后内存使用量增加了.我认为该程序不会释放旧对象.所以我试着用gc()as

result <- foreach(i = 10:100, 
        .combine = list,
        .multicombine = TRUE)  %dopar%  {

          set.seed(i)

          a <- replicate(i, rnorm(20)) 
          b <- replicate(i, rnorm(20))

          list(x = a + b, y = a - b)
         gc()

        } 
Run Code Online (Sandbox Code Playgroud)

它似乎有用,但我没有得到我想要的结果.然后我尝试在每个循环之前收集垃圾,但似乎不起作用.

result <- foreach(i = 10:100, 
        .combine = list,
        .multicombine = TRUE)  %dopar%  {
          gc()
          set.seed(i)

          a <- replicate(i, rnorm(20)) 
          b <- replicate(i, rnorm(20))

          list(x = a + b, y = a - b)    
        } 
Run Code Online (Sandbox Code Playgroud)

有没有办法解决这个问题?谢谢你们,任何建议将不胜感激.PS.这段代码只是为了重现,我的真实模拟程序比这复杂得多.所以我不想太多地改变程序结构.

Gar*_*ini 3

我认为您没有遇到任何所谓的“内存泄漏”,因为使用更多的迭代foreach只会创建一个更大的数组。如果您的问题是是否真的gc()有帮助,我建议您阅读Hadley Wickham 撰写的 Advanced R 的内存使用章节,其中他指出:

\n
\n

尽管您可能在其他地方读过,但 \xe2\x80\x99s 永远不需要调用gc()自己

\n
\n

不管怎样,我试图找出代码中可能存在的内存泄漏,将其分为您描述的三个函数或可能性。

\n
library(foreach)\nlibrary(doParallel)  \nf1 <- function(uu = 10:100){\n  no_cores <- detectCores() - 2\n  cl<-makeCluster(no_cores)\n  registerDoParallel(cl)\n  result1 <- foreach(i = uu, .combine = list, \n                     .multicombine = TRUE)  %dopar%  {\n                      set.seed(i)\n                      a <- replicate(i, rnorm(20)) \n                      b <- replicate(i, rnorm(20))\n                      gc()\n                      return(list(x = a + b, y = a - b))\n                      } \n  stopCluster(cl)\n  return(result1)\n}\nf2 <- function(uu = 10:100){\n  no_cores <- detectCores() - 2\n  cl<-makeCluster(no_cores)\n  registerDoParallel(cl)\n  result1 <- foreach(i = uu, .combine = list, \n                     .multicombine = TRUE)  %dopar%  {\n                       gc()\n                       set.seed(i)\n                       a <- replicate(i, rnorm(20)) \n                       b <- replicate(i, rnorm(20))\n                       return(list(x = a + b, y = a - b))\n                     } \n  stopCluster(cl)\n  return(result1)\n}\nf3 <- function(uu = 10:100){\n  no_cores <- detectCores() - 2\n  cl<-makeCluster(no_cores)\n  registerDoParallel(cl)\n  result1 <- foreach(i = uu, .combine = list,  .multicombine = TRUE)  %dopar%  {\n                       set.seed(i)\n                       a <- replicate(i, rnorm(20)) \n                       b <- replicate(i, rnorm(20))\n                       return(list(x = a + b, y = a - b))\n                     } \n  stopCluster(cl)\n  return(result1)\n}\n\nlibrary(pryr)\nmem_used() # 214 MB\nmem_change(NULL) # 864 B\ngc() # whatever\nmem_change({res1 <- f1(); rm(res1)}) # 2.11 kB\nmem_change({res1 <- f2(); rm(res1)}) # 2.11 kB\nmem_change({res1 <- f3(); rm(res1)}) # 2.11 kB\nmem_change({res1 <- f1(10:250); rm(res1)}) # 2.11 kB\nmem_change({res1 <- f2(10:250); rm(res1)}) # 2.11 kB\nmem_change({res1 <- f3(10:250); rm(res1)}) # 2.11 kB\n
Run Code Online (Sandbox Code Playgroud)\n

除此之外,我尝试profvis使用 std 输入 (10:100) 运行三个函数,并得到以下一般时间和记忆:

\n

f1():在此输入图像描述f2():在此输入图像描述f3():在此输入图像描述

\n

我不相信profvis记忆的结果,而是相信时间的结果。一般来说,我不会用于gc()释放并行循环中的空间。

\n