参考文章
GC 之 Minor/Young/Major GC 的区别
Java 新生代、老生代和永久代详解
图解
我们平时提及 Minor GC、Young GC、Major GC,它们之间的关系是怎样的呢?
如下图 1 所示,一图胜千言,这是 JDK8 之前的,JDK8 上没有最右边的 Perm 区。
图 1 Minor/Young/Major GC 的关系
此图来自国外的一篇博客,建议读者阅读原文,链接地址。
从图 1 来看 Minor GC 发生在 Eden 区;Young GC 发生在 Eden、S0、S1 区;Major GC 发生在 Old 区。
引申出一个问题,Full GC 与上述这些的关系呢?
对于 Full GC,其实这里有一个更加合适的说法,就是说 Full GC 指的是针对新生代、老年代、永久代的全体内存空间的垃圾回收,所以称之为 Full GC。
从字面意思上也可以理解,Full 就是整体的意思,所以就是对 JVM 进行一次整体的垃圾回收,把各个内存区域的垃圾都回收掉。
JDK8 的 heap 图,觉得挺好的,原文链接,建议自行查看原文。
图 2 JDK8 的 heap 图
元空间
当老年代也满了装不下的时候,就会抛出 OOM。
- 永久代
指内存的永久保存区域,主要存放 Class 和 Meta(元数据)的信息。
Class 在被加载的时候元数据信息会放入永久区域,但是 GC 不会在主程序运行的时候清除永久代的信息。所以这也导致永久代的信息会随着类加载的增多而膨胀,最终导致 OOM。注意:在 Java8 中,永久代已经被移除,被一个称为 “元数据区”(元空间)的区域所取代。
元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此默认情况下元空间的大小仅仅受本地内存的大小限制。类的元数据放入 native memory, 字符串池和类的静态变量放入 java 堆中。 这样可以加载多少类的元数据就不再由 MaxPermSize 控制,而由系统的实际可用空间来控制。