【问题标题】:Does GC collects garbage from Metaspace?GC 是否从 Metaspace 收集垃圾?
【发布时间】:2014-10-20 09:15:32
【问题描述】:

我一直认为垃圾收集器只清除堆,现在我这么认为。

在 java 8 中 permGen 被删除并被 Metaspace 取代。

据我了解,元空间是垃圾收集的(https://stackoverflow.com/a/24075360/2674303)

谁从元空间收集垃圾?

【问题讨论】:

  • 我不确定我是否理解你,但我认为 GC 只能从 Java 堆收集垃圾,但 Metaspace 不在 Java 堆内。

标签: java garbage-collection java-8 dispose


【解决方案1】:

我认为您的困惑源于口语“垃圾收集”一词,该词被广泛使用,但并未真正描述托管环境中发生的情况。

内存管理是一个复杂的过程,简单来说就是:

  • 识别哪些对象是垃圾,这实际上是一个确定哪些对象可达(读作:不是垃圾)并认为所有没有遇到的都是垃圾的过程
  • 如有必要,将对象引用排入引用队列和/或触发终结
  • 回收以前被垃圾占用的内存,也可能反过来:有时活动对象被移动到不同的内存空间

因此,对于不包含 Java 对象的内存空间,前两点通常没有多大意义,这似乎是您的问题所在。解决前两点的算法通常只处理 Java 堆(定义为包含普通 Java 对象实例和类似结构化数据的空间)。

您链接的声明“元空间已被 GCed”似乎主要解决了 第三个​​ 点。这是关于 Metaspace 中的内存在不再需要时可能会被回收的事实。这并不意味着它需要遍历元空间内的实时引用或类似的东西。显然,当关联的 ClassClassLoader 变得无法访问时,类元数据就过时了,它们都是生活在 Java 堆上的普通(嗯,几乎)对象。

所以当元空间大小达到限制时,会触发垃圾回收,但对于上面的前两个项目,它不会处理元空间,因为它不是元空间可以告诉你Class是否已经变成没用过。这将是一个普通的垃圾收集,但它将是一个“Full GC”或任何当前使用的 GC 算法对模式的术语,该模式包括在包含类和类加载器的内存段(也称为“生成”)内收集垃圾。

一旦ClassClassLoader 堆实例被收集,它们关联的元空间数据也可以在清理过程中被回收。

【讨论】:

  • 所以将使用不同的垃圾收集器算法来收集元空间? (意味着它既不是次要GC也不是主要GC)因为收集元空间的方式与收集堆不同
  • @amarnathharish 好吧,必须有专门的代码来释放元空间中的内存,这与其他空间不同,但是由于存储在元空间中的工件与类相关联,因此取决于在类的集合上能够回收这块内存。并且检测到无法访问的类通常发生在主要 GC(又名“Full GC)”中。
  • 感谢您的快速响应,所以只要老年代被填满元空间调整大小发生时,就会发生完整的GC?当发生这种情况时,它会收集 旧代和元空间,而不管需要收集什么?
  • @amarnathharish 您可以这样看,或者您认为要回收元空间中的内存,它需要收集旧代(以识别无法访问的类),而在收集旧代时由于老年代被填满,有关可回收元空间工件的知识是免费的副产品。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-26
  • 2023-03-30
  • 1970-01-01
  • 2011-07-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多