JVM线程优化
原理
业务进程运行期间,JVM会开启回收线程进行及时编译和堆空间管理垃圾回收等操作,JVM运行线程多少对系统性能有直接影响。通过资源监控找到占用CPU较高的JVM线程,并做相关调优处理,能优化业务程序运行性能。
通过下面方法找到占用CPU较高的JVM线程:
- 利用top命令找到Java进程ID,如此示例的进程ID是16498。
- 利用top -H -p <pid>命令跟踪进程下面各个线程的CPU占用情况,如下图这里取16810线程做示例。
- 将线程ID转换成16进制,可以使用Windows操作系统计算器转换,如16810转换为41aa。
- 使用jstack命令查询此线程栈信息:
jstack -l <进程ID> | grep <线程16进制ID>
可以看出此线程名称是"cronJobScheduler_Worker-8",这个不是JVM的线程。下图中"Gang worker#0 (Parallel GC Threads)"、"Concurrent Mark-Sweep GC Thread"、"Gang worker#1 (Parallel CMS Threads)"都属于JVM线程。
修改方式
- 方法一:
- 如果GC线程占用CPU较高且系统CPU资源充足,可以通过增加GC回收线程数量,降低GC线程的回收压力。不同垃圾回收方法设置GC方法参数不尽相同,CMS使用-XX:ParallelCMSThreads参数设置,Parallel使用参数-XX:ParallelGCThreads设置。其他垃圾回收算法参数设置可参考《JVM垃圾回收算法与参数配置》。
下面是将CMS的GC线程数量设置成2的示例:
# /path/java -XX:ParallelCMSThreads=2 <other parameters>
- 名称带有“C1”或“C2”的线程一般为即时编译(JIT)线程,若此类线程占用CPU较高,首先可以适当增加参数-XX:CompileThreshold的值,减少触发JIT频率,C2模式下该参数默认值是10000,C1模式下默认为1500。将JIT阈值设置为20000 :
# /path/java -XX:CompileThreshold=20000 <other parameters>
- 如果GC线程占用CPU较高且系统CPU资源充足,可以通过增加GC回收线程数量,降低GC线程的回收压力。不同垃圾回收方法设置GC方法参数不尽相同,CMS使用-XX:ParallelCMSThreads参数设置,Parallel使用参数-XX:ParallelGCThreads设置。其他垃圾回收算法参数设置可参考《JVM垃圾回收算法与参数配置》。
- 方法二:
调整编译线程数量,设置-XX:+CICompilerCountPerCPU=true,编译线程数依赖于处理器核数自动配置;设置-XX:+CICompilerCountPerCPU=false -XX:+CICompilerCount=N,强制设定总编译线程数为N。例如,将JIT线程数量设置为4:
# /path/java -XX:+CICompilerCountPerCPU=false -XX:+CICompilerCount=4 <other parameters>
- 方法三:
- 增加线程数量会导致CPU利用率上升,上下文切换增多可能会引起业务性能下降,调整参数需要根据业务实际情况进行优化适配。
- 关闭JIT可能会对业务性能有影响。
父主题: 优化调优方法