jvm垃圾回收

2020-10-13  本文已影响0人  奋斗的韭菜汪

1、判断垃圾

垃圾回收主要讨论的是堆中对象的回收问题
GC Root:虚拟机栈中的本地变量表(线程中的栈帧会指向本地变量表中的变量,说明有线程正在执行调用本地变量表中的变量,见jvm概述图3)、static变量、常量引用(两者存在方法区中)、本地方法栈(jvm C语言实现)中的变量、类加载器、Thread类(代表的是java线程)
2、垃圾回收
回收算法:
1、标记和清除算法(缺点:a、产生大量内存空间碎片,b、全空间扫描标记和清除扫描两次,效率比较低)
2、复制算法(内存空间划分为两个部分,时刻保持一半为空,避免产生空间碎片,同时也导致空间浪费)suriver区为该算法的实现
3、标记整理算法(先标记,再将存活对象向一侧移动)
垃圾回收器会实现这些算法(垃圾收集器还需要适合不同分代年龄,适合新生代young Serial、ParNew、Parallel Scavenge、G1;适合老年代old CMS、Serial Old、Parallel Old、G1 )
新生代:复制算法(为什么要使用复制算法:新生代相对存活对象较少,对象朝生夕死,复制成本较低)
老年代:标记算法(标记清除,标记整理)对象生命周期较长
分析新生代和老年代不难推出垃圾收集器收集算法实现:新生代垃圾收集器主要是复制算法的实现,老年代主要是标记算法的实现

image.png
分析垃圾收集器的几个维度(单/多线程(并行)工作、适合的代、收集算法、优缺点)
Serial:单线程,
image.png
ParNew:(并行)多线程,
image.png
Parallel Scavenge:多线程,相比ParNew更加关注吞吐量
Serial Old 标记整理,
image.png

Parallel Old 标记整理、同样关注吞吐量
CMS: Concurrent Mark Sweep 并发类的垃圾收集器(用户线程和垃圾收集可以同时进行,关注的是停顿时间)

image.png

G1:jdk1.9的默认收集器,可以设置停顿时间(在指定停顿时间下保证最高的吞吐量),先分阶段标记,然后筛选回收(为什么还要筛选,是为了满足前面提到的,在指定停顿时间下保证最高的吞吐量),也就是说可能会不完全回收所有标记的垃圾,

image.png

垃圾收集器调优的过程就是关注的是:吞吐量和停顿时间
jvm调优:
(1)GC收集器的停顿时间和吞吐量
停顿时间:垃圾收集器进行垃圾回收终端(浏览器、app..)执行响应的时间-->G1可以设置比较小的停顿时间适合和用户交互比较多的场景,如web程序
吞吐量:运行用户代码的时间/(运行用户代码的时间+垃圾收集时间)--> 用户代码执行占用cpu资源的时间比较大,适合跑任务,运算任务等
停顿时间小收集器:CMS、G1[set pause time] -->并发类的收集器
吞吐量优先的:Parallel Scavenge、Parallel Old -->并行类的收集器
串行收集器:Serial、Serial Old,适用于内存比较小,嵌入式设备
ZGC也是一个收集器,对G1进行了优化,追求更小的停顿时间接近10ms(这也是java发展的方向,早期java并不知道java后面发展会大量应用于web开发)
(官方)如果对停顿时间没有非常严格的要求,最好使用jvm默认的收集器
(2)内存使用的维度

如何选择合适的垃圾收集器
官网 :https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html#sthr ef28
优先调整堆的大小让服务器自己来选择 如果内存小于100M,使用串行收集器 如果是单核,并且没有停顿时间要求,使用串行或JVM自己选 如果允许停顿时间超过1秒,选择并行或JVM自己选 如果响应时间最重要,并且不能超过1秒,使用并发收集器 对于G1收集
** 再次理解G1**
JDK 7开始使用,JDK 8非常成熟,JDK 9默认的垃圾收集器,适用于新老生代。
判断是否需要使用G1收集器?
(1)50%以上的堆被存活对象占用
(2)对象分配和晋升的速度变化非常大
(3)垃圾回收时间比较长
**如何开启需要的垃圾收集器 **
(1)串行 -XX:+UseSerialGC -XX:+UseSerialOldGC
(2)并行(吞吐量优先): -XX:+UseParallelGC -XX:+UseParallelOldGC
(3)并发收集器(响应时间优先) -XX:+UseConcMarkSweepGC -XX:+UseG1GC

上一篇下一篇

猜你喜欢

热点阅读