JVM回顾(一)
2018-03-30 本文已影响21人
厌恶狡诈心机
1 查看JVM中运行的进程信息 jps
jps -m
-q 不输出类名、Jar名和传入main方法的参数
-m 输出传入main方法的参数
-l 输出main类或Jar的全限名
-v 输出传入JVM的参数
#示例
7212 Resin --root-directory /usr/local/resin/ -conf /usr/local/resin/conf/resin-vv-live-imdb.xml -server app-vv-live-imdb -socketwait 59240 restart -Xmx2048m -XX:MaxPermSize=512m -Dresin.server=app-vv-live-imdb -Djava.util.logging.manager=com.caucho.log.LogManagerImpl -Djava.system.class.loader=com.caucho.loader.SystemClassLoader -Djava.endorsed.dirs=/usr/java/jdk1.7.0_51/jre/lib/endorsed:/usr/local/resin//endorsed:/usr/local/resin//endorsed -Djavax.management.builder.initial=com.caucho.jmx.MBeanServerBuilderImpl -Djava.awt.headless=true -Djava.awt.headlesslib=true -Dresin.home=/usr/local/resin/ -Xss1m
1027 Jps -m -v -Dapplication.home=/usr/java/jdk1.8.0_144 -Xms8m
2 打印JAVA进程堆栈跟踪信息命令 jstack
命令示例:
./jstack -l 27509
- 注意
如发现如下问题,通常的原因是 /tmp/hsperfdata_用户名/ 目录下没有对应pid文件
处理方法:
1、选择进程对应用户执行命令,A用户启动的程序,root也看不到栈信息。
2、确认对应目录下的pid文件没有需要重启。
./jstack -l 4945
4945: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
#解决方法
su 启动Java程序用户 -c "jstack -l 4945"
返回结果例如
"nioEventLoopGroup-5-1" #137 prio=10 os_prio=0 tid=0x0000000000bb7000 nid=0x6eca runnable [0x00007fe905cc6000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000000cab2c768> (a io.netty.channel.nio.SelectedSelectionKeySet)
- locked <0x00000000cab2d828> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000cab2c670> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:759)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:400)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:873)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
- 结果分析
关键字
死锁,Deadlock(重点关注)
执行中,Runnable
等待资源,Waiting on condition(重点关注)
等待获取监视器,Waiting on monitor entry(重点关注)
暂停,Suspended
对象等待中,Object.wait() 或 TIMED_WAITING
阻塞,Blocked(重点关注)
停止,Parked
含义如下所示:
Deadlock:死锁线程,一般指多个线程调用间,进入相互资源占用,导致一直等待无法释放的情况。
Runnable:一般指该线程正在执行状态中,该线程占用了资源,正在处理某个请求,有可能正在传递SQL到数据库执行,有可能在对某个文件操作,有可能进行数据类型等转换。
Waiting on condition:等待资源,或等待某个条件的发生。具体原因需结合 stacktrace来分析。
如果堆栈信息明确是应用代码,则证明该线程正在等待资源。一般是大量读取某资源,且该资源采用了资源锁的情况下,线程进入等待状态,等待资源的读取。
又或者,正在等待其他线程的执行等。
如果发现有大量的线程都在处在 Wait on condition,从线程 stack看,正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。
一种情况是网络非常忙,几乎消耗了所有的带宽,仍然有大量数据等待网络读写;
另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。
另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。
Blocked:线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。
Waiting for monitor entry 和 in Object.wait():Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。
从下图中可以看出,每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。在 “Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是 “in Object.wait()”。
转载于:http://www.cnblogs.com/zhengyun_ustc/archive/2013/01/06/dumpanalysis.html
1图
定位进程内最耗费CPU的线程
top -Hp pid
转换16进制 printf "%x\n" 十进制数
jstack -l 21711 | grep 16进制数