为什么gc()没有释放内存?

我使用64 GB RAMWindows 64位计算机上运行模拟。 内存使用达到55% ,在完成模拟运行后,我通过rm(list=ls())删除工作空间中的所有对象,然后是double gc()

我认为这会为下一次模拟运行释放足够的内存,但是实际上内存使用量仅下降1% 。 咨询了很多不同的论坛,我找不到一个令人满意的解释,只有模糊的评论,如:

“根据您的操作系统,释放的内存可能不会返回到操作系统,而是保留在进程空间中。”

我想查找以下信息:

  • 1)哪个操作系统和在哪个条件下释放内存不会被返回到操作系统,以及
  • 2)如果除了closuresR还有其他补救措施,并且在下次模拟运行时再次启动?

你如何检查内存使用情况? 通常情况下,虚拟机会分配一些内存来存储数据。 部分分配可能未被使用并标记为空闲。 GC所做的是发现没有从其他地方引用的数据,并将相应的内存块标记为未使用,这并不意味着该内存被释放到操作系统。 从VM的angular度来看,现在有更多的空闲内存可以用于进一步的计算。

正如其他人问你是否经历了内存不足的错误? 如果没有,那么没有什么可担心的。

编辑: 这和这应该是足够了解如何内存分配和垃圾收集在R工作。

从第一个文件:

偶尔会尝试将未使用的页面释放回操作系统。 当页面被释放时,多个空闲节点等于R_MaxKeepFrac倍,每个类的分配节点数被保留。 发布不需要满足此要求的页面。 每个R_PageReleaseFreq级别1或级别2集合都会尝试释放页面。

EDIT2:

要查看使用过的内存,请尝试将详细设置为TRUE的gc()

 gc(verbose=T) 

内存中有10'000'000个整数的结果:

 Garbage collection 9 = 1+0+8 (level 2) ... 10.7 Mbytes of cons cells used (49%) 40.6 Mbytes of vectors used (72%) used (Mb) gc trigger (Mb) max used (Mb) Ncells 198838 10.7 407500 21.8 350000 18.7 Vcells 5311050 40.6 7421749 56.7 5311504 40.6 

在抛弃对它的引用之后,这里是:

 Garbage collection 10 = 1+0+9 (level 2) ... 10.7 Mbytes of cons cells used (49%) 2.4 Mbytes of vectors used (5%) used (Mb) gc trigger (Mb) max used (Mb) Ncells 198821 10.7 407500 21.8 350000 18.7 Vcells 310987 2.4 5937399 45.3 5311504 40.6 

正如你所看到的Vcell使用的内存从40.6Mb下降到2.4Mb。

R垃圾收集器在以下(不是那么)微妙的方式中是不完美的:它不移动对象(即它不压缩内存),因为它与C库交互的方式。 ( 其他一些语言/实现也遭受这种困扰,但是其他语言/实现也不得不与C进行交互,从而设法实现紧凑的世代GC ,而不会遇到这个问题)。

这意味着如果你轮stream分配内存的小块,然后丢弃,更大的块为更多的永久对象(这是进行string/正则expression式处理时,这是一个常见的情况),然后你的内存变得分散 ,垃圾收集器无能为力它:内存被释放,但不能被重用,因为空闲块太短。

解决问题的唯一方法是保存所需的对象,重新启动R并重新加载对象。

因为你正在做rm(list=ls()) ,也就是说,你不需要任何对象,所以你不需要保存和重载任何东西,所以在你的情况下,解决scheme正是你想要避免的 – 重新启动R

PS。 垃圾收集是一个非常重要的话题。 例如, Ruby在20年中使用了5(!)个不同的GCalgorithm 。 Java GC并不吸引人,因为Sun / Oracle和IBM在其各自的GC实现上花费了许多人力和时间 。 另一方面,R和Python的糟糕的GC – 因为没有人打扰投入必要的人工年。