java自带的jvm分析工具
这段时间觉得很有必要对java的内存分析工具进行熟悉,这样以后出现机器负载较高,或者反应很慢的时候,我就可以查找原因了。上网搜了搜,发现下面这些是比较常用的,然后我在机器上试试了,把结果也贴出来哈。
1.jps
类似ps-ef|grepjava显示java进程号
2.jstack
打印jvm内存的堆栈信息,打印出来的结果类似
2010-04-2120:10:51
FullthreaddumpJavaHotSpot(TM)ServerVM(10.0-b23mixedmode):
"RMITCPConnection(idle)"daemonprio=10tid=0x08f7a000nid=0x1928waitingoncondition[0x4b234000..0x4b2350a0]
java.lang.Thread.State:TIMED_WAITING(parking)
atsun.misc.Unsafe.park(NativeMethod)
-parkingtowaitfor<0x68ec3430>(ajava.util.concurrent.SynchronousQueue$TransferStack)
atjava.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
atjava.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:424)
atjava.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323)
atjava.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:874)
atjava.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:944)
atjava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:906)
atjava.lang.Thread.run(Thread.java:619)
"AttachListener"daemonprio=10tid=0x08a08800nid=0x18e4runnable[0x00000000..0x4b142068]
java.lang.Thread.State:RUNNABLE
"recvMsgTP-1_sharereport_groupId_refund_[daily]-33040763-3-thread-10"prio=10tid=0x08f3d400nid=0x2985waitingoncondition[0x4b192000..0x4b192fa0]
java.lang.Thread.State:WAITING(parking)
atsun.misc.Unsafe.park(NativeMethod)
-parkingtowaitfor<0x6af53cd8>(ajava.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
atjava.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
atjava.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1925)
atjava.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:358)
atjava.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:946)
atjava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:906)
atjava.lang.Thread.run(Thread.java:619)
这样我们可以根据打印结果,看到现在哪些线程在运行,哪些在等待,进而再找到线程等待执行的原因,从而分析出程序执行变慢的原因。
3.jstat-gcutil
对java垃圾回收信息的统计,这样我们可以得到垃圾回收是否正常,fullGC的执行时间和频率是否正常等。
S0S1EOPYGCYGCTFGCFGCTGCT
8.340.0053.2413.1451.77747.5962825.09932.695
8.340.0053.5413.1451.77747.5962825.09932.695
8.340.0053.9313.1451.77747.5962825.09932.695
8.340.0053.9313.1451.77747.5962825.09932.695
8.340.0053.9313.1451.77747.5962825.09932.695
8.340.0053.9713.1451.77747.5962825.09932.695
8.340.0053.9813.1451.77747.5962825.09932.695
8.340.0053.9813.1451.77747.5962825.09932.695
8.340.0053.9813.1451.77747.5962825.09932.695
8.340.0054.0113.1451.77747.5962825.09932.695
8.340.0054.4013.1451.77747.5962825.09932.695
后面加T表示的是Time执行时间,单位是秒
YGCFGC分别是youngGC和FullGC执行的次数。
4.jinfo-flags
可以查询java运行的参数设置
AttachingtoprocessID21982,pleasewait...
Debuggerattachedsuccessfully.
Servercompilerdetected.
JVMversionis10.0-b23
-Dprogram.name=run.sh-Xms1024m-Xmx1024m-XX:NewSize=320m-XX:MaxNewSize=320m-XX:PermSize=96m-XX:MaxPermSize=96m-Djava.awt.headless=true-Dsun.net.client.defaultConnectTimeout=10000-Dsun.net.client.defaultReadTimeout=30000-Xdebug-Xrunjdwp:transport=dt_socket,address=18787,server=y,suspend=n-Djava.net.preferIPv4Stack=true
5.jmap
-histo
打印出java中的对象信息,包括实例个数,字节大小和完整类名。
num#instances#bytesclassname
----------------------------------------------
1:66049566381608[C
2:13411934894408[B
3:7344130779672[I
4:67040116089624java.lang.String
5:12506215547312<constMethodKlass>
6:42729613673472java.util.TreeMap$Entry
7:32858513143400java.util.concurrent.ConcurrentHashMap$EntryIterator
8:12506210010904<methodKlass>
9:1322058504792[Ljava.lang.Object;
10:1738067883528<symbolKlass>
这些命令后面都要加上java进程号。