一、JVM性能调优
1.系统调优多层面
在进行jvm调优之前,假设项目的架构调优和代码调优已经进行过或者是针对当前项目是最优的。这两个是jvm调优的基础,并且架构调优是对系统影响最大的,我们不能指望一个系统架构有缺陷或者代码层次优化没有穷尽的应用,通过jvm调优令其达到一个质的飞跃,这是不可能的。
另外,在调优之前,必须得有明确的性能优化目标, 然后找到其性能瓶颈。之后针对瓶颈的优化,还需要对应用进行压力和基准测试,通过各种监控和统计工具,确认调优后的应用是否已经达到相关目标。
2.JVM调优单层面
整个堆大小=新生代大小 + 老生代大小 + 永久代大小。 对堆大小的指定需要指定相关参数。如果不采用以下参数进行指定的话,虚拟机会自动选择合适的值,同时也会基于系统的开销自动调整。
参数说明:
分代 | 参数 | 描述 |
堆大小 | -Xms | 初始堆大小,默认为物理内存的1/64(<1GB) 注意:32位操作系统理论上最大只支持4G内存,64位操作系统最大能支持128G内存 |
-Xmx | 最大堆大小,一般讲Xms, Xmx设置成一样的大小,避免超过Xms后,内存重新整理 | |
新生代 | -XX:NewSize | 新生代空间大小初始值 |
-XX:MaxNewSize | 新生代空间大小最大值 | |
-Xmn | 新生代空间大小,此处的大小是(eden+2 survivor space) 默认为xmx的三分之一 | |
永久代 | -XX:PermSize | 永久代空间的初始值&最小值 |
-XX:MaxPermSize | 永久代空间的最大值 | |
老年代 | -xmx减去-xmn | 老年代大小 |
-Xmx减去-XX:NewSize的值 | 老年代初始值 | |
-Xmx值减去-XX:MaxNewSize的值 | 老年代最小值 |
注意:在设置的时候,如果关注性能开销的话,应尽量把永久代的初始值与最大值设置为同一值,因为永久代的大小调整需要进行FullGC 才能实现。
3.生产环境这些参数怎么指定
5.tomcat和jar两种方式中的jvm参数设置
启动jar包的参数配置方式
java -Xms8000m -Xmx8000m -Xmn6000m -jar luckydrawall-0.1.1.jartomcat的配置示例:配置tomcat的catalina.sh
JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS -Xms8000m -Xmx8000m -Xmn6000m"6.总结:
1、多数的Java应用不需要在服务器上进行GC优化;
2、多数导致GC问题的Java应用,都不是因为我们参数设置错误,而是代码问题;
3、在应用上线之前,先考虑将机器的JVM参数设置到最优(最适合);
4、减少创建对象的数量;
5、减少使用全局变量和大对象;
6、GC优化是到最后不得已才采用的手段;
7、在实际使用中,优化代码比优化GC参数要多得多;
二、常见线上问题
- 内存泄露
- 某个进程突然cpu飙升
- 线程死锁
- 响应变慢
三、问题定位
一般会基于数据收集来定位,而数据的收集离不开监控工具的处理,比如:运行日志、异常堆栈、GC日志、线程快照、堆快照等。经常使用恰当的分析和监控工具可以加快我们的分析数据、定位解决问题的速度。四、JVM常见监控指令
①jps:查看java进程信息-q 不输出类名、Jar名和传入main方法的参数
-l 输出main类或Jar的全限名
-m 输出传入main方法的参数
-v 输出传入JVM的参数
②jstat:查看堆内存各部分的使用量,以及加载类的数量。
命令的格式如下:jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]
a.类加载统计:jstat -class 8705
说明:
Loaded:加载class的数量
Bytes:所占用空间大小
Unloaded:未加载数量
Bytes:未加载占用空间
Time:时间
b.垃圾回收统计: jstat -gc 8705
说明:
S0C:第一个幸存区的大小(kb)
S1C:第二个幸存区的大小(kb)
S0U:第一个幸存区的使用大小(kb)
S1U:第二个幸存区的使用大小(kb)
EC:伊甸园区的大小(kb)
EU:伊甸园区的使用大小(kb)
OC:老年代大小(kb)
OU:老年代使用大小(kb)
MC:方法区大小(kb)
MU:方法区使用大小(kb)
CCSC:压缩类空间大小(kb)
CCSU:压缩类空间使用大小(kb)
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间(s)
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间(s)
GCT:垃圾回收消耗总时间(s)
c.堆内存统计: jstat -gccapacity 8705
NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
EC:伊甸园区的大小
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:当前老年代大小
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代gc次数
FGC:老年代GC次数
d.新生代垃圾回收统计: jstat -gcnew 8705
e.新生代内存统计: jstat -gcnewcapacity 8705
f.老年代垃圾回收统计: jstat -gcold 8705
g.老年代内存统计: jstat -gcoldcapacity 8705
h.总垃圾回收统计: jstat -gcutil 8705
③jinfo:可以用来查看正在运行的Java应用程序的扩展参数,甚至支持在运行时,修改部分参数
命令格式:jinfo -flags process_id
④jmap: java 内存映射工具(自己百度学习下)
⑤jhat:jvm堆快照分析工具(自己百度学习下)
⑥jstack:java堆栈跟踪工具(自己百度学习下)
五、监控工具
对jvm监控的常见可视化工具,除了jdk本身提供的Jconsole和visualVm以外,还有第三方提供的jprofilter,perfino,Yourkit,Perf4j,JProbe,MAT等。对于VisualVm来说,比较推荐使用,它除了对jvm的侵入性比较低以外,还是jdk团队自己开发的,相信以后功能会更加丰富和完善。
jprofilter对于第三方监控工具,提供的功能和可视化最为完善,目前多数ide都支持其插件,对于上线前的调试以及性能调优可以配合使用。
- 排查故障技巧
找到该进程下最耗费cpu的线程:top -Hp pid指令
排查申请资源问题:jmap -heap pid 查看新生代,老年代堆内存的分配大小以及使用情况,看是否本身分配过小。