性能调优之jvm(理论篇二)
垃圾回收
什么场景下该使用什么样的垃圾回收策略?
1.内存要求苛刻:尽量提高回收效率,腾出更多内存
2.CPU使用率高:尽量降低回收频率,让CPU更多的执行业务而不是回收垃圾
JVM内存结构中,哪些区域需要关注垃圾回收?
1.只有堆和方法区需要关注垃圾回收
2.堆是垃圾回收的主要区域,主要回收的创建的对象
3.方法区回收不需要使用的常量和类
4.栈和程序计数器是线程隔离的,随着线程的产生而产生,随着线程的消亡而消亡,所以不需要关注垃圾回收
对象在什么时候才能被回收?
1.引用计数法(当出现循环引用时无能为力,JAVA未采用此算法)
2.可达性分析:如果某个对象到根对象没有引用链相连,则认为对象不可达,可以回收
GC Roots包括哪些对象?
1.虚拟机栈中引用的对象
2.方法区中类静态属性引用的对象
3.方法区中常量引用的对象
4.本地方法栈中JNI(即Native方法)引用的对象
什么是引用?
1.强引用
2.软引用
3.弱引用
4.虚引用
可达性算法注意点;
一个对象即使不可达,也不一定会被回收
finalize()方法的建议
1.避免使用finalize()方法,操作不当可能会导致问题
2.finalize()方法优先级低,何时被调用无法确定,因为什么时间发生GC无法确定
3.建议使用try...catch..finally来代替finalize()
垃圾回收算法
1.三种基本回收算法
1.标记-清除
2.标记-整理
3.复制
2.两种综合回收算法
1.分代收集算法
定义:根据对象的存活周期,把内存分为多个区域,不同区域使用不同的垃圾回收算法(主流,各种商业虚拟机的堆内存垃圾收集基本上都采用分代收集算法)
回收类型:
1.新生代回收(Minor GC|Yong GC)
1.新生代采用复制收集算法
2.对象新创建的时候,会先存放在伊甸园
3.触发回收条件:当伊甸园空间不足,就会触发新生代回收,把伊甸园里面存活的对象复制到存活区的其中一个,下次回收则会复制到另外一个,循环往复,即复制回收算法
2.老年代回收(Major GC)
1.对象每经历一次垃圾回收,如果还存活,年龄就会+1,当年龄达到阈值(默认值15),就会进入老年代
2.Major GC的时候,一般会伴随着一次Minor GC,所以一般认为,Major GC≈Full GC
3.触发回收条件:
1)老年代空间不足
2) 元空间不足
3)要晋升到老年代的对象所占用的空间大于老年代的剩余空间
4)显示调用System.gc()
3.老年代采用标记-清除或者标记-整理收集算法
3.整个堆的回收(Full GC)
4.例外情况:
1.新创建的对象不一定分配到伊甸园
2.对象不一定要达到年龄才会进入老年代
分带算法的好处:
1.更有效的清除不再需要的对象
2.提升了垃圾回收的效率
分带算法调优原则:
1.合理设置surviver区域的大小,避免内存浪费
2.让GC尽量发生在新生代,尽量减少Full GC的发生
2.增量算法
定义:每次只收集一小片区域的内存空间的垃圾
相关JVM参数
垃圾收集器
相关术语:
1.Stop The World
定义:简写为STW,也叫全局停顿,jav代码停止运行,native代码继续运行,但不能与JVM进行交互
原因:多半由于垃圾回收导致,也可能又dump线程,死锁检查,dump堆等导致
危害:服务停止,没有相应;主从切换,危害生产环境
2.并行收集:多个垃圾收集线程并行工作,但是收集的过程中,用户线程处于等待状态
3.并发收集:指用户线程与垃圾收集线程同时工作
4.吞吐量
定义:CPU用于运行用户代码的时间与CPU总消耗时间的比值
公式:运行用户代码时间/(运行用户代码时间+垃圾回收时间)
新生代收集器
1.Serial收集器
1.最基本,发展历史最悠久的收集器
2.复制算法
3.单线程
4.简单,高效(指相对于其他收集器的单个线程而言)
5.收集过程全程Stop The World
6.适用场景:
1.客户端程序,应用以-client模式运行时,默认使用的就是Serial
2.单核机器
2.ParNew收集器
1.Serial收集器的多线程版,除了多线程,其他和Serial收集器一模一样
2.适用场景:主要用来和CMS收集器配合使用
3.Parallel Scavenge收集器
1.也叫吞吐量优先收集器
2.采用的也是复制算法
3.也是并行的多线程收集器,这一点和ParNew类似
4.特点:
1)可以达到一个可控制的吞吐量
2)自适应GC策略
5.适用场景:比较注重吞吐量的场景
老年代收集器
1.Serial Old收集器
1.Serial收集器的老年代版本
2.标记-整理算法,其他与Serial一致
3.可以和Serial/ParNew/Parallel Scavenge三个新生代垃圾收集器配合使用
4.CMS收集器出现故障的时候,会用Serial Old作为后备
2.Parallel Old收集器
1.Parallel Scavenge收集器的老年代版本
2.标记-整理算法,其他与Parallel Scavenge一致
3.只能和Parallel Scavenge配合使用
4.适用于关注吞吐量的场景
3.CMS收集器
1.全称:Concurrent Mark Sweep 并发标记清除
2.并发收集器
3.标记-清除算法
4.执行过程较前面几款复杂很多
1.初始标记
2.并发标记
3.并发预清理(不一定执行)
4.并发可终止的预清理阶段(不一定执行)
5.重新标记
6.并发清理
tips:为什么不是并发整理,而是并发清除呢?
因为没有STW,并发情况下很难做到整理,所以采用清除
7.并发重置
5.优点:
1)STW时间比较短
2)大多数过程并发执行
6.缺点
1)CPU资源比较敏感,并发阶段可能导致应用吞吐量下降
2)无法处理浮动垃圾,并发清除阶段用户产生的垃圾本次GC无法清除,只能等待下一次GC
3)不能等到老年代几乎满了才开始收集,因为用户线程需要申请内存空间
4)存在内存碎片
7.适用场景
希望系统停顿时间短,响应速度快的场景,比如各种服务器应用程序
G1收集器
1.全称:Garbge First
2.是一款面向服务器端应用的垃圾收集器
3.既可以用在新生代,也可以用在老年代
4.G1的堆内存布局和前面几款有很大区别
1)Region:整个堆内存被等分成一块块区域,对应上图每一个小方格
2)Humongous:用来存放大对象,如果大小超过region的一半,就会放在Humongous Region里面,如果超过一个Region的大小,会放在多个连续的Humongous Region里面
6.回收机制:
1)Young GC
2)Mixed GC(增量算法)
3)Full GC
7.如何减少Full GC?
8.特点:
1.可以作用在整个堆
2.可控的停顿
MaxGCPauseMillis=200
3.无内存碎片
9.适用场景
1)占用内存比较大的应用(6G以上)
2)替换CMS收集器
9.选择G1还是CMS?
1)jdk8,如果内存大于6G可以选择G1,小于6G可以选择CMS
2)jdk9以上,只能适用G1,CMS已经被废弃