简介
java程序的性能问题剖析是一个很艰难的问题。尤其是对于一个非常复杂的程序来说,剖析起来更是头疼。
还好JVM引入了JFR,能够通过JFR来监控和剖析JVM的各种事件。通过这些事件的剖析,咱们能够找出潜在的问题。
明天咱们就来介绍一下对java性能剖析比拟重要的一些JFR事件。
GC性能事件
一般来说,GC会对java程序的性能操作产生比拟重要的影响。咱们能够应用jfr监控jdk.GCPhasePause事件。
上面是一个jdk.GCPhasePause的例子:
jfr print --events jdk.GCPhasePause flight_recording_1401comflydeanTestMemoryLeak89268.jfr
输入后果:
jdk.GCPhasePause { startTime = 19:51:49.798 duration = 41.1 ms gcId = 2 name = "GC Pause"}
通过GCPhasePause事件,咱们能够统计总的GC pause工夫和均匀每一次GC pause的工夫。
一般来说GC是在后盾执行的,所以GC自身的执行工夫咱们并不需要关注,因为这并不会影响到程序的性能。咱们须要关注的是应用程序因为GC暂停的工夫。
思考上面两种状况,第一种独自的GC导致GC pause工夫过长。第二种是总的GC pause工夫过长。
如果是第一种状况,那么可能须要思考换一个GC类型,因为不同的GC类型在pause工夫和吞吐量的均衡间接会有不同的解决。同时咱们须要缩小finalizers的应用。
如果是第二种状况,咱们能够从上面几个方面来解决。
- 减少heap空间大小。heap空间越大,GC的间隔时间就越长。总的GC pause工夫就会越短。
- 尽量减少tmp对象的调配。咱们晓得为了晋升多线程的性能,JVM会应用TLAB技术。一般来说小对象会调配在TLAB中,但如果是大对象,则会间接调配在heap空间中。然而大部分对象都是在TLAB中调配的。所以咱们能够同时关注TLAB和TLAB之外的两个事件:jdk.ObjectAllocationInNewTLAB和dk.ObjectAllocationOutsideTLAB。
- 缩小调配频率。咱们能够通过jdk.ThreadAllocationStatistics来剖析。
同步性能
在多线程环境中,因为多线程会竞争共享资源,所以对资源的同步,或者锁的应用都会影响程序的性能。
咱们能够监控jdk.JavaMonitorWait事件。
jfr print --events jdk.JavaMonitorWait flight_recording_1401comflydeanTestMemoryLeak89268.jfr
咱们看一个后果:
jdk.JavaMonitorWait { startTime = 19:51:25.395 duration = 2 m 0 s monitorClass = java.util.TaskQueue (classLoader = bootstrap) notifier = N/A timeout = 2 m 0 s timedOut = true address = 0x7FFBB7007F08 eventThread = "JFR Recording Scheduler" (javaThreadId = 17) stackTrace = [ java.lang.Object.wait(long) java.util.TimerThread.mainLoop() line: 553 java.util.TimerThread.run() line: 506 ]}
通过剖析JavaMonitorWait事件,咱们能够找到竞争最强烈的锁,从而进行更深层次的剖析。
IO性能
如果应用程序有很多IO操作,那么IO操作也是会影响性能的要害一环。
咱们能够监控两种IO类型:socket IO和File IO。
绝对应的事件有:dk.SocketWrite,jdk.SocketRead,jdk.FileWrite,jdk.FileRead。
代码执行的性能
代码是通过CPU来运行的,如果CPU应用过高,也可能会影响到程序的性能。
咱们能够通过监听jdk.CPULoad事件来对CPULoad进行剖析。
jfr print --events jdk.CPULoad flight_recording_1401comflydeanTestMemoryLeak89268.jfr
看下运行后果:
jdk.CPULoad { startTime = 19:53:25.519 jvmUser = 0.63% jvmSystem = 0.37% machineTotal = 20.54%}
如果jvm应用的cpu比拟少,然而整个machine的CPU使用率比拟高,这阐明了有其余的程序在占用CPU。
如果JVM本人的CPU应用就很高的话,那么就须要找到这个占用CPU的线程进行进一步剖析。
其余有用的event
除了下面提到的event之外,还有一些其余有用的咱们能够关注的event。
比方线程相干的:jdk.ThreadStart,jdk.ThreadEnd,jdk.ThreadSleep,jdk.ThreadPark。
如果你应用JMC,那么能够很直观的查看JFR的各种事件。
所以举荐大家应用JMC。
本文作者:flydean程序那些事本文链接:http://www.flydean.com/jvm-diagnostic-perform-issue/
本文起源:flydean的博客
欢送关注我的公众号:程序那些事,更多精彩等着您!