JVM调优实践

JVM调优实践
jwang对于一个系统要部署上线时,则一定会对JVM进行调整,很少会不经过任何调整直接上线。否则很容易出现线上系统频繁FullGC造成系统卡顿、CPU使用频率过高、系统无反应等问题。
服务器性能指标
对于一个应用来说通常重点关注的性能指标主要是吞吐量、响应时间、QPS、TPS等、并发用户数等。而这些性能指标又依赖于系统服务器的资源,如:CPU、内存、磁盘IO、网络IO等。对于这些指标数据的收集,通常可以根据Java本身的工具或指令进行查询,详情参照第一天。
1)CPU:
CPU资源一般可以使用vmstat来采样(例如每秒采样一次: vmstat 1)查看CPU上下文切换。如下:
$ vmstat 1 |
- us:用户占用CPU的百分比
- sy:系统(内核和中断)占用CPU的百分比
- id:CPU空闲的百分比
- in: 系统中断数
- cs: 每秒上下文切换次数
- r: 可运行进程数,包括正在运行(Running)和已就绪等待运行(Waiting)的。在负载测试中,其可接受上限通常不超过CPU核数的2倍。
CPU使用率通常用us + sy来计算,一般大于80%说明,CPU资源出现瓶颈。
2)内存
根据上述信息,其中已经输出了内存的信息
- free: 系统可用内存,对于稳定运行的系统,free可接受的范围通常应该大于物理内存的20%。
- so/si : 每秒从内存写入到SWAP的数据大小/每秒从SWAP读取到内存的数据大小。如果出现频繁的swap交换,会影响系统性能,需要一起注意。
- swpd:系统当前的swap空间占用。可以和so/si 综合分析。如果swpd为0 ,内存资源没有成为瓶颈。
3)磁盘
对于磁盘,首要关注使用率,IOPS和数据吞吐量,在Linux服务区,可以使用iostat来获取这些数据。
$ iostat -dxk 1 |
- %util: 衡量device使用率的指标。处理I/O请求的时间与统计时间的百分比.大于60%的话,会影响系统性能。
- r/s, w/s :每秒处理,读、写的请求数量。
- rkB/s,wkB/s :每秒读/写的数据大小。
JVM参数调优
对于JVM调优,主要就是调整年轻代、年老大、元空间的内存空间大小及使用的垃圾回收器类型。
1)设置堆的初始大小和最大大小,为了防止垃圾收集器在初始大小、最大大小之间收缩堆而产生额外的时间,通常把最大、初始大小设置为相同的值。
-Xms:设置堆的初始化大小 |
2) 设置年轻代中Eden区和两个Survivor区的大小比例。该值如果不设置,则默认比例为8:1:1。Java官方通过增大Eden区的大小,来减少YGC发生的次数,但有时我们发现,虽然次数减少了,但Eden区满
的时候,由于占用的空间较大,导致释放缓慢,此时STW的时间较长,因此需要按照程序情况去调优。
-XX:SurvivorRatio |
3)年轻代和老年代默认比例为1:2。可以通过调整二者空间大小比率来设置两者的大小。
-XX:newSize 设置年轻代的初始大小 |
4)线程堆栈的设置:每个线程默认会开启1M的堆栈,用于存放栈帧、调用参数、局部变量等,但一般256K就够用。通常减少每个线程的堆栈,可以产生更多的线程,但这实际上还受限于操作系统。
-Xss 对每个线程stack大小的调整,-Xss128k |
5)一般一天超过一次FullGC就是有问题,首先通过工具查看是否出现内存泄露,如果出现内存泄露则调整代码,没有的话则调整JVM参数。
6)系统CPU持续飙高的话,首先先排查代码问题,如果代码没问题,则咨询运维或者云服务器供应商,通常服务器重启或者服务器迁移即可解决。
7)如果数据查询性能很低下的话,如果系统并发量并没有多少,则应更加关注数据库的相关问题。
8)如果服务器配置还不错,JDK8开始尽量使用G1或者新生代和老年代组合使用并行垃圾回收器。




