1、常见问题
  • 硬件升级系统反而变得卡顿

    垃圾回收器选择不当,重新选择适当的垃圾回收器

    1.8之前叫做method are 方法区,1.8之后叫做meta space元数据区

    栈溢出设置-Xss大小

2、垃圾回收器常用算法

内存分区:eden区+s0(survivor)+s1(survivor)+old区

  • 扫描整个内存区域

    • serial + serial old
    • parallel scavenge + parallel old(jdk8垃圾回收器)
    • parnew+cms
  • 开始讲内存区域分成很多歌小份

    • g1 (jdk9默认的垃圾回收器)
  • 开始讲内存区域分成不同大小的区域

    • zgc
    • shenandoah

3、名词解释

  • stw:stop thread wait 线程停止等待

  • 三色标记

  • 颜色指针

  • ygc:eden区内存不足时会进行ygc(多线程并发执行)

  • fgc:old区内存不足时会进行fgc(system.gc())

4、cms算法

cms 在进行fgc的时候会耗费大量时间

  • 步骤:
    concurrent字样表示垃圾回收线程和程序线程在同时工作

    • initial mark(初始标记)

      通过gcroots找到根对象,这个阶段会有stw现象,不过根对象比较少,stw时间很短

    • concurrent mark(并发标记)(核心思想)

      会发生多次并发标记,通过根对象往下找。最耗时的阶段,因为并发执行,所以不会有stw的现象

    • remark(重新标记)

      在并发标记中有引用关系发生变化时,会对这些对象进行重新标记,会有stw现象,由于刚进行完并发标记,所以改动的引用关系不是很多,所以stw时间很短。

    • concurrent sweep(并发回收)

      将标记为垃圾的对象进行清理,回收进行时产生的新的垃圾被称为浮动垃圾,这些垃圾会在下次gc的时候清理

  • 缺点:
    • 碎片化
    • 浮动垃圾

5、g1算法

采用分而治之的思想,将内存从1m->2m。。2^n 分成多个区域,最大32m

  • g1的fgc在jdk10之前是单线程的串行执行,所以fgc效率特别低,应当减少fgc频率。

    • 如果G1产生FGC,你应该做什么?
    1. 扩内存

    2. 提高CPU性能(回收的快,业务逻辑产生对象的速度固定,垃圾回收越快,内存空间越大)

    3. 降低MixedGC触发的阈值,让MixedGC提早发生(默认是45%),可以减少fgc的频率。

  • 新老年代比例分配

    一般不需要手动指定大小,不要使用手工指定,g1会以预测的停顿时间为标准,进行动态的比例划分调整新老年代区域比例

  • 优点

    • 并发收集

    • 压缩空闲空间不会延长gc的时间

    • 更易预测gc暂停时间

    • 适用不需要很高的吞吐量的场景,但是需要很高的响应时间

  • mixedgc类似于cms

    如果g1产生fgc可以降低mixedgc触发的阈值,提前让mixedgc提前发生

    • mixed是g1的正常回收算法,当对象占内存比达到阈值,会触发mixed进行垃圾回收;

    • g1的fgc使用的算法是serial算法回收垃圾。

  • 三色标记法

    • 三色标记有白色、黑色、灰色

      白色:未被标记的对象

      黑色:自身和成员变量都被标记完成

      灰色:自身被标记,成员变量未被标记

    • increment update 增量更新

      关注引用的增加,将黑色重新标记为灰色

    • SATB (snapshot at the beginning)

      关注引用的删除,当引用被删除,会将引用推送到gc的堆栈,保证删除的引用还可以被gc扫描到。