为什么GC()释放内存?(Why does gc() not free memory?)

2019-07-18 22:00发布

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

我认为,这将仅通过1%的自由下一个模拟运行足够的内存,但实际上内存使用量下降 。 咨询了很多不同的论坛,我不能找到一个满意的解释,只是含糊的意见,例如:

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

我想找到的信息:

  • 1)操作系统和在何种条件下释放的内存不会返回到OS,并且
  • 2)如果有任何其他救济超过了未来模拟运行再次关闭R和创业吗?

Answer 1:

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

正如其他人问你遇到内存不足的错误? 如果没有,那么就没有什么可担心的。

编辑: 这和这应该是足够的了解如何内存分配和垃圾收集工作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

正如你可以看到Vcells使用的内存从下跌至40.6Mb 2.4MB。



Answer 2:

所述R垃圾收集器是在以下(不那么)隐蔽的方式不完善:它移动的,因为它与交互的方式的对象(即,它不紧凑存储器) C库。 (一些其他语言/实现从这个挨得过,但其他人 ,尽管也有与互动C ,管理有压缩代GC 存在这个问题)。

这意味着,如果你轮流分配的内存小块然后将其抛弃,更持久的对象较大的块(这是一种常见的情况做串/正则表达式处理时),那么你的记忆变得支离破碎和垃圾收集无能为力它:内存被释放,但不能被重新使用,因为空闲块太短。

解决该问题的唯一方法是救你想要的对象,重新启动R并重新加载的对象。

既然你正在做的rm(list=ls())即你不需要任何对象,你并不需要保存和重新加载任何东西,所以,你的情况,该解决方案恰恰是要避免的东西-重启R

PS。 垃圾收集是一个非常不平凡的话题。 例如, 红宝石使用5(!)不同的GC算法超过20年 。 Java的GC不吸因为Sun / 甲骨文和IBM花了很多程序员年各自的GC的实现。 在另一方面,R和Python有糟糕的GC - 因为没有人费心去投入必要的人 - 年 - 他们是很受欢迎。 这是更坏就是更好的为您服务。

PPS。 相关: R:使用`strsplit`运行内存



文章来源: Why does gc() not free memory?