JVM垃圾回收机制

问题引入:

    谈谈JVM垃圾回收机制

怎样判断一个对象是否是垃圾?

判断是否是垃圾有两种方式,(1)引用计数法,无法解决循环引用问题,Java不使用,Python使用

             (2)可达性分析,以GC Root为根进行可达性遍历,无法被遍历到的判定为垃圾

ps:什么是GC Root根?虚拟机栈中的局部变量表,方法区中的静态变量引用的对象,方法区中常量引用的对象,本地方法栈中引用的对象(native)

典型垃圾回收算法:(1)标记清除算法 :先标记垃圾,再清除。会产生内存碎片,效率也不太高

          (2)复制算法:不会产生内存碎片,但将内存缩小到原来的一半,占用空间。性能取决于存活对象的多少,如果存活对象很多,很费时

          (3)标记整理算法:先标记,再清除,再整理内存。比较耗时。

          (4)分代收集算法:当前商业虚拟机的垃圾收集都采用“分代收集”算法,根据对象存活周期的不同将内存分为几块。一般是把java对分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中每次垃圾收集时都有大量对象死去,只有少量对象存活,所以就采用复制算法,只需要付出少了存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对他进行分配担保,就要使用“标记-清除”或“标记-整理”算法

常见垃圾回收方式:(1)Serial 串行垃圾回收。Full GC时只有一个线程回收垃圾用户线程等待。STW时间长

         (2)Parallel 并行垃圾回收。Full GC时多个线程回收垃圾用户线程等待。STW时间短

         (3)CMS 并发垃圾回收。Full GC时用户线程与垃圾回收线程宏观上同时进行(可能微观上交替运行),形如多线程。宏观上没有STW

         (4)G1垃圾回收

常见的垃圾回收器

(1)串行垃圾回收器 Serial,SerialOld:cclient模式(单核CPU)下性能好(简单高效);他们之间互相自动匹配。对应JVM参数:-XX:+UseSerialGC。开启后会使用Serial(Young区)+SeiialOld(老年区)的收集器组合,表示年轻代使用复制算法,老年代使用标记整理算法。

(2)并行垃圾收集器 ParNew,ParallerOld:垃圾回收时多个线程回收垃圾,速度快

(3)并行垃圾回收器Paraller Scavenge:多数计算机默认的垃圾回收器,新生代老年代都是多线程并行回收,(Paraller(Young区)+ParallerOld(老年区))相当于串行收集器在新生代和老年代的并行化(都会产生STW)。他常被称为吞吐量优先级收集器。

 (4)CMS CMS收集器是一种以获得最短停顿时间为目标的收集器。使用标记清除算法。(其他老年代收集器都使用标记清除整理算法)其整个过程分为“初始标记”,“并发标记”,“重新标记”,“并发清除”四个阶段。初始标记和重新标记仍需STW,初始i标记用于标记与GC ROOT直接关联的对象,速度很快。并发标记是以GC ROOT关联对象进行可达性分析的过程。重新标记是标记在并发标记过程中因用户线程运行导致标记变动的过程。最后进行对象清除。

  CMS缺点:<1>,对CPU敏感,CPU要求高。  <2>,无法处理浮动垃圾,因为在清除垃圾时用户线程在并发运行,这个时间可能会有新的垃圾产生。并且CMS收集器不能等老年代满了再启动,因为还要预留一部分给正在并发运行的用户线程。如果清理还没有完成老年代就满了,本次CMS收集失败,启动后备SerialOld收集器,将消耗大量时间。<3>,CMS使用标记清除算法,会产生内存碎片。综合2,3点缺点,CMS收集器是有一些机会启用后备Serial收集器的,这也正是设置后备收集器的目的。

如何选择垃圾收集器:

 

 几种垃圾收集器小总结:

 

JVM参数有三种:

标配参数(-version,-help这种的原始低级的,了解)

X参数:(Java运行模式,解释执行Xint,默认的混合模式Xmixed等,了解)

XX参数:(1)Boolean类型(比如是否打印GC细节设置,了解)设置方式:-XX:+参数名称

     (2) 设值类型 key=vaule

如何查看参数:

jps -l   查看进程号             jinfo -flag key名称 进程号

 

盘点JVM初始化数据家底:查看初始值:java -XX:PrintFlagsInitial命令  查看修更新值:java -XX:PrintFlagsFinal -version

 

调优常见的参数:-Xms  : 初始堆内存大小,默认物理内存1/64

          -Xmx  :最大分配堆内存大小,默认1/4

        -Xss  : 设置单个线程栈的大小,一般0.5-1M   

        -Xmn  :设置年轻代大小 

        -XX:SurvivorRatio  : 设置年轻代中eden与s0/s1的比例,-XX:SurvivorRatio=8标识8:1:1

        -XX:NewRatio  : 设置堆中年轻代与老年代的比例,默认-XX:NewRatio=2,即老年代:年轻代=2:1

        -XX:MaxTenuringThreshold  : 设置垃圾的最大年龄,默认-XX:MaxTenuringThreshold=15

 

 

posted @ 2020-03-07 12:50  codeFlyer  阅读(115)  评论(0编辑  收藏  举报