jvm内存模型: 堆、栈、程序计数器、本地方法栈、元空间
堆 : 新生代、老年代(jvm调优主要内存)
-
程序计数器: 程序计数器是一块较小的内存空间,可看作当前线程正在执行的字节码的行号指示器
1.1 如果当前线程正在执行的是- Java方法
计数器记录的就是当前线程正在执行的字节码指令的地址 - 本地方法
那么程序计数器值为undefined
1.2 作用
程序计数器有两个作用字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、 循环、异常处理
在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。
- Java方法
文献:
https://blog.csdn.net/truelove12358/article/details/100531911
jvm调优:
jvm调优实际就是对堆空间不同区的大小、比例调节,
jvm调优过程一般都是对full gc 的调节从而减少Full GC 的发生
Young GC(新生代回收)、Full GC(整个堆回收),所以发生Full GC会比Young GC耗时,因此需要尽量减少发生Full GC的次数
Minor GC发生在Eden区;Young GC发生在Eden、S0、S1区)
一. 堆划分区域: 新生代(Eden+2个survivor) + 老年代
一般新生代各区的调节比例为8:1:1 (伊甸园Eden:幸存区S0:幸存区S1)即Eden为8/10,具体原因看文献
目前生产新生代各区比例配置: -XX:SurvivorRatio=8
-Xms(初始堆大小)=5G -Xmx(最大堆大小)=5G -Xmn(新生代大小)=2G -XX:SurvivorRatio=8
为了防止垃圾收集器在最小、最大之间收缩堆而产生额外的时间,通常把最大、最小设置为相同的值;
二. 发生Full GC的原因:
- 老年代被写满了(主因)
调优时尽量让对象在新生代GC时被回收、让对象在新生代多存活一段时间和不要创建大对象,避免直接在旧生代创建对象 。所谓的大对象指的是那种对象大小较大、很长的字符串以及数组 - System.gc()被显示调用
垃圾回收不要手动触发,尽量依靠JVM自身的机制 - 持久代Pemanet Generation空间不足(java8后淘汰)
增大Perm Gen空间,避免太多静态对象 , 控制好新生代和旧生代的比例
三. 对象在堆各区过程:
虚拟机采用了分代思想去管理对象,为了区分对象对应分配的区域,虚拟机为每个对象设置了一个Age计数器;
对象一开始会被分配在新生代Eden区,当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC;如果对象在一个MinorGC(只回收Eden区)过后再仍然存活,就将被移到survivor区中,然后age+1。对象每经历一次Minor GC age就会增加1岁,当达到某个阈值的时候(默认为15岁),就会晋升到老年代。可以通过设置参数-XX:MaxTenuringThreshold来设置晋升的年龄。
然而对于虚拟机来说,并不是一定要达到这个要求才能晋升为老年代。还有一种情况就是某个年龄的对象大小的总和大于survivor区的一半时,年龄大于或等于这个年龄的对象都将进入到老年区。
四. GC垃圾回收:
GC Roots 可达性分析算法, 分析是否存活,被引用
回收算法:标记复制算法,标记清除算法,标记整理,分代收集
Minor GC 和 Full GC 的区别,触发条件,以及空间分配担保策略?
Minor GC: - 年轻代空间回收内存被称为 Minor GC,标记复制算法,发生一次GC,在eden区域的对象会到,会到from区域中再到to区域,每次gc还在的话对象的年龄就会加1,经过n次gc还在,默认是15岁,就会去老年代了
edne区域不足时,触发gc
空间分配担保策略就是开启条件判断,在发生Minor GC 之前,虚拟机会先检查老年代最大可用连续空间是否大于新生代所有对象大小总和
如果大于,直接GC,
如果小于,判断是不是有设置一个参数,担当值,没有的话直接full gc
Full GC: - Full GC 是清理整个堆空间的 —— 包括年轻代、老年代和元空间
使用标记清除算法,所以会产生很多的碎片空间,并且时间长。老年代空间不足触发
五. 分析dump文件结果,判断是否需要优化
如果各项参数设置合理,系统没有超时日志出现,GC频率不高,GC耗时不高,那么没有必要进行GC优化,如果GC时间超过1-3秒,或者频繁GC,则必须优化。
注:如果满足下面的指标,则一般不需要进行GC:
Minor GC执行时间不到50ms;
Minor GC执行不频繁,约10秒一次;
Full GC执行时间不到1s;
Full GC执行频率不算频繁,不低于10分钟1次;
六. jvm 配置:
文献:
https://zhuanlan.zhihu.com/p/58897189 (有JVM调优参数参考部分)
https://blog.csdn.net/peerless_fu/article/details/83550246(新生代各区比值设为8的原因)
https://blog.csdn.net/u010723709/article/details/47356507