jvm垃圾收集器

默认垃圾收集器

jdk9之前:serial  +  serial old

jdk9及之后:G1

Serial

HotSpot新生代默认回收器

1.只能单线程回收  标记-复制算法

2.再回收时需要“Stop the world”

3.回收效率高,所有线程都停下来知道垃圾回收回收完

ParNew

是Serial的并行版本

1.标记-复制

2.多条回收线程并行,但是回收线程和用户线程不能并行

3.需要“stop the world”

Parallel Scavenge

1.标记 - 复制

2.多线程并行 需要“stop the world”

3.吞吐量优先,可以通过配置设置吞吐量大小

吞吐量 = 运行用户代码时间/(运行用户代码 + 垃圾回收时间)

新生代设置相对大一些,吞吐量相对会大一些,因为垃圾回收不是那么频繁

处理器资源稀缺,想优先处理用户代码 就可以把吞吐量设置大一些

4.可以设置停顿时间大小(这里是指停顿时间,后边的cms、G1控制收集时间因为不需要stop the

                                                                                                                                              world)

  可以设置吞吐量大小,

5.可以通过参数设置,开启自适应策略 收集器会根据运行情况自动调整新生代老年代大小等参数

Serial Old

1.标记 - 整理

2.单线程回收 回收的时候不会出现新的垃圾

3.老年代

Parallel Old

1.标记 - 整理

2.多线程并行,同时并发

3.老年代的回收器

CMS

1.标记-清除

2.并发以获取最短停顿时间为目标 

3.步骤:

初始标记

并发标记

重新标记  处理用户线程并行期间产生变化的数据

并发清除

4.缺点: 并发操作更消耗cpu资源影响用户线程,浮动垃圾

5.优化:

缺点一可以忽略

缺点二设置阈值当堆占用68%或90%时就触发垃圾回收 并发失败就stop the world full GC

其他 处理内存碎片,设置参数在Full GC之前先进行碎片整理

G1

算法:标记-复制

思想:部分回收让停顿时间可控

特点:1.不分新生代老年代,将整个堆分若干个region

          2.每次回收的时候是将存活的对象复制到空的region中,原来的region清空

          3.有Region 中有一类Hummongous区域用来存储大对象(对象超过了region的一半)

    4.可以设置单次回收所允许的最长时间,G1会根据是时间评估具体需要回收哪些region,这个时间一般为一百至三百毫秒

    5.执行步骤:

      初始标记

      并发标记:只有这个阶段是并发的

      重新标记:处理用户线程并行期间发生变化的数据 SATB

      筛选收集:标记-复制

只有并发标记阶段是并发的其他的都需要stop the worldZGC可以在筛选收集阶段实现并发

新生代的一般是标记-复制,老年代的一般是标记-整理cms标记清除 G1标记复制

G1相对CMS的优点和弱点

1.G1的优秀特点

    1)G1可以设置最大停顿时间  cms不可以

    2)G1是region的内存布局  cms分新生代老年代

    3)G1是按受益来动态确定收集行为

    4)G1采用标记-复制算法,没有内存碎片

2.弱点

    1)内存占用高:

          G1为了解决region问题,每个region上都有一个卡表,所以G1的记忆集会占用超过堆20%的内存空间,cms也使用了卡表来处理跨代指针,但是只有新生代老年代所以占用内存较小

      2)负载高:

          cms需要使用写后屏障维护卡表

          G1需要使用写后屏障维护卡表,还需要使用写前屏障记录指针(G1用了原始快照搜索算法所以需要这个指针)

各个回收器之间的关系:

新生代:  serial  --并行-->  parNew  --吞吐量-->  parallel scavenge 

老年代:  serial old            cms                            parallel old

综合: G1

经典组合: ps + po

                parnew + cms + serial old

                G1

如何选择垃圾收集器?

影响选择的因素:

1.关注点(吞吐量、延迟、内存占用)

2.基础设施(处理器数量、内存大小、操作系统是window还是Linux)

3.JDK的发行商、版本号

几种收集器的特点

C1:综合性能好 花钱

ZGC:使用比较新的软硬件版本,注重延迟

Shenandoah:window

CMS:堆内存在4G到6G,硬件和JDK比较落后

G1:堆内存更大一点考虑G1

注重吞吐量: ps + po

注重低延迟,对停顿时间敏感:

                    内存小: cms

                    内存够大:G1 ZGC

整个内存回收过程是什么样的流程?

1.大对象直接进入老年代  可设置界限

2.多次回收仍存活的进入老年代

分代年龄判定

新生代每回收一次年龄加一,超过15进入老年代

动态年龄判定

相同年龄的对象占用survivor一半内存,那么等于或大于这个年龄的对象直接进入老年代

3.内存担保

  新生代回收时(复制算法 survivor到另一个survivor)不够用,就直接将无法容纳的对象放入老年代,如果老年代也放不下就Full GC

你可能感兴趣的:(jvm垃圾收集器)