Java-Heap被划分为新生代和老年代
新生代:主要使用复制算法(Coping)和标记清除算法(Mark-Sweep)
老年代:主要使用标记压缩算法(Mark-Compact)
文章目录
Serial垃圾收集器(单线程、复制算法)
Serial 是最基本的垃圾收集器,使用的是复制算法(Copying)
Serial 是一个单线程的垃圾收集器,只会使用一个CPU或一条线程去完成垃圾收集工作,并且在进行垃圾收集的同时,必须暂停其他所有的工作线程,直到垃圾收集结束(STW)
ParNew垃圾收集器(Serial + 多线程)
ParNew 是Serial的多线程版本,也适用复制算法,除了使用多线程进行垃圾回收之外,其余的行为和Serial完全一样,ParNew在进行垃圾收集的过程中同样需要暂停所有其他工作线程(STW)
ParNew默认开启和CPU数目相同的线程数,可以通过 -XX:ParallelGCThreads
参数来限制垃圾收集器的线程数
Parallel Scavenge收集器(多线程复制算法、高效)
PS也使用的是复制算法,也是一个多线程的垃圾收集器,是对ParNew的优化版本,可以进行自适应调节。更关注程序达到一个可控制的吞吐量,高吞吐量可以最高效率的利用CPU时间 - 由JVM来实现。
Serial Old收集器(单线程、标记压缩算法)
Serial Old 是默认的老年代垃圾收集器
主要有两个用途:
- 在JDK1.5之前的版本中,与PS收集器搭配使用
- 作为老年代中使用CMS的后备垃圾收集方案
Serial + Serial Old
ParNew/ParllelScavenge + Serial Old
CMS收集器(多线程、标记清除算法)
ConcurrentMarkSweep收集器,主要目标是获取最短垃圾回收停顿时间,多线程 + 标记清除算法
CMS的工作机制:
- 初始标记
- 只标记GC Roots能直接关联的对象,速度很快
- 但仍需要暂停所有的工作线程,需要STW
- 并发标记
- 进行GC Roots 跟踪的过程,和用户线程一起工作,不需要STW
- 重新标记
- 为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录
- 需要STW
- 并发清除
- 清除垃圾对象,与用户线程同步工作
- 不需要STW
耗时最长的过程:并发标记、并发清除
CMS的问题:
因为CMS使用的是MarkSweep算法,所以会产生垃圾碎片,一旦CMS清理后内存空间依旧不足以存放对象,则会触发SerialOld来继续清理内存,虽然SerialOld 使用的是MarkCompact算法,但是SerialOld是单线程,STW严重。
G1收集器(GarbageFirst)
先挖个坑,比较麻烦后期扩展
特点:逻辑分代、物理不分代
优势:
- 基于标记压缩算法,不产生内存碎片
- 可以精确控制停顿时间,在不牺牲吞吐量的前提下,实现低停顿垃圾回收
G1是一种服务端应用使用的垃圾收集器,目标是用在多核,大内存的机器上,它在大多数情况下可以实现指定的GC暂停时间,同时还能保持较高的吞吐量
垃圾回收器 & 内存
Serial:几十兆
PS+PO:上百兆-几个G
CMS:20G上下
G1:上百G
ZGC:4T