面试一二三之JVM的垃圾回收

46 阅读2分钟

如何判定对象是否该回收

1、引用计数法

计算对象被引用的次数,被引用一次就+1,在回收对象时,如果对象引用数为0,则回收。

缺点:无法判断互相引用的对象。

2、可达性分析算法

从GCRoot对象开始,根据引用关系标记,这样,被标记的都是存活的对象。

GCRoot对象:

  1. 虚拟机栈里的对象

  2. 方法区栈里的对象

  3. 方法区里的常量

  4. 方法区里的静态对象

垃圾回收算法

  • 标记-清除:将存活的对象标记,清理掉未标记的对象

    优点:处理逻辑简单

    缺点:回收完成后,内存不连续,内存碎片较多

  • 标记-复制:将内存分为两块,每次只用一块,当一块用满后,将存活的对象迁移到另一内存块,再清空当前内存块

    优点:没有内存碎片

    缺点:只能使用一半的内存

  • 标记-整理:从内存的一端开始使用,清理的时候,将存活的对象移到另一端,然后清理掉其他的内存

    优点:没有内存碎片

    缺点:性能较 标记-复制 算法差

常见的垃圾回收器

  • Parallel Scavenge:

    注重吞吐量的新生代回收器,采用多线程+标记复杂算法

    Java8默认

  • Parallel Old

    搭配Parallel Scavenge的老年代回收期,采用多线程标记整理算法

  • CMS

    目标是最小的停顿时间,并发标记的老年代回收期,整个流程分为首次标记、并发标记、再次标记、并发清理四个阶段,在首次标记时,标记GCRoot时才暂停线程

  • G1

    Java9开始的默认回收算法,将内存分为很多个小块,每块都可以作为年轻代和老年代,不仅如此,还有一个大对象块