GC(垃圾分代收集)

GC(垃圾收集机制)

一、如何识别一个垃圾对象?

  1. 引用计数法
  2. GCRoot引用链

二、分代收集机制

一般垃圾回收发生在堆区,很少有在方法区发生,所以方法区被称为永久代

  1. 新生代

    • 包括Eden、from survivor、to survivor三个区

    • 在这个区采用的是复制收集算法,即:

      1. 先将Eden、from survivor中存活的对象复制到to survivor区中
      2. 清空Eden、from survivor两个区
      3. 最后将to survivor区中的对象复制到from survivor区中,并清空to survivor区
  2. 从新生代到老年代

    • 大对象直接进入老年代
    • 新生代survivor中年龄达到15的对象,移入老年代
    • 为survivor区作担保,其内存已满而不能存储的对象存储在老年代中
  3. 老年代

    • 老年代因为对象的存活率高(复制的代价就要高),也没有担保空间,所以采用标记清除/整理法

    • CMS收集:

      1. stop the world初步标记(初步标记GCROOT直接关联的对象)
      2. 并发标记(进行GCROOTS跟踪过程)
      3. stop the world重新标记(修正在2阶段产生的垃圾)
      4. 并发清除

      优点:可以知道大量的标记和清除都在并发阶段执行,所以其垃圾收集停顿时间极短,可以提高用户的交互体验。

  4. 为什么要分代收集呢?

    可以知道很多对象都是朝生夕死的,那么新生代就起到了一个缓存一样的作用,集中的处理新垃圾,而存活率高的对象则放在老年代,使垃圾收集的代价降低了

  5. Minor GC和Full GC

    新生代快满的时候就会触发Minor GC,Minor GC是比较频繁的GC,一般耗时较少

    老年代快满了或者System.gc()建议,则会触发Full GC,Full GC会对整个堆进行GC,甚至包含几次Minor GC,所以耗时较长

  6. 永久代

    主程序运行时似乎不会对永久代进行回收?

    在jdk1.8中,为了防止方法区溢出,将方法区改为元数据区,将其放到的堆外内存(本地内存)中去了,那么他的大小就不受JVM的限制了。

原文地址:https://www.cnblogs.com/lnu161403214/p/11197218.html