Java Platform, Standard Edition Troubleshooting Guide, Release 8 (oracle.com)
JDK8 引入了Java Mission Control(Java任务控制)、jcmd、Java Flight Recorder用来定位处理JVM和Java程序相关问题。
jstat: 利用Java HotSpot虚机内置功能,提供关于运行程序的性能、资源消耗情况,对于定位性能问题(尤其是关于堆大小、垃圾回收等)。举例:jstat -gcutil 2834 250 7,attach到2834进程,每间隔250毫秒,取7次样本数据,jstat -gcnew -h3 2834 250;jstat -gcoldcapacity -t 2189 250 3.
visualgc: The visualgc Tool (oracle.com)
jstack: attach到指定进程或core文件打印所有线程的堆栈信息,也能检测到死锁。举例:jstack -F 8321,强制打印8321的线程栈信息。jstack
J
A
V
A
H
O
M
E
/
b
i
n
/
j
a
v
a
c
o
r
e
,
j
s
t
a
c
k
−
m
2117
j
h
a
t
:
检
测
J
a
v
a
堆
放
并
找
出
哪
个
对
象
占
用
最
多
空
间
,
以
及
发
现
不
再
使
用
待
未
能
释
放
的
对
象
。
j
m
a
p
:
打
印
运
行
的
j
v
m
内
存
相
关
统
计
或
内
存
文
件
的
内
存
统
计
。
举
例
:
j
m
a
p
−
h
e
a
p
2960
,
j
m
a
p
−
h
i
s
t
o
2960
获
取
类
相
关
的
堆
直
方
图
,
j
m
a
p
−
h
i
s
t
o
/
u
s
r
/
b
i
n
/
j
a
v
a
c
o
r
e
(
A
t
t
a
c
h
i
n
g
t
o
c
o
r
e
c
o
r
e
f
r
o
m
e
x
e
c
u
t
a
b
l
e
/
u
s
r
/
b
i
n
/
j
a
v
a
)
j
d
b
:
命
令
行
调
试
器
,
它
采
用
J
D
I
(
J
a
v
a
D
e
b
u
g
I
n
t
e
r
f
a
c
e
)
发
起
或
建
立
到
目
标
J
V
M
的
连
接
。
举
例
:
j
d
b
−
l
i
s
t
c
o
n
n
e
c
t
o
r
s
打
印
可
用
的
连
接
器
,
j
d
b
−
c
o
n
n
e
c
t
s
u
n
.
j
v
m
.
h
o
t
s
p
o
t
.
j
d
i
.
S
A
P
I
D
A
t
t
a
c
h
i
n
g
C
o
n
n
e
c
t
o
r
:
p
i
d
=
9302
,
j
d
b
−
c
o
n
n
e
c
t
s
u
n
.
j
v
m
.
h
o
t
s
p
o
t
.
j
d
i
.
S
A
C
o
r
e
A
t
t
a
c
h
i
n
g
C
o
n
n
e
c
t
o
r
:
j
a
v
a
E
x
e
c
u
t
a
b
l
e
=
JAVA_HOME/bin/java core,jstack -m 2117 jhat: 检测Java堆放并找出哪个对象占用最多空间,以及发现不再使用待未能释放的对象。 jmap: 打印运行的jvm内存相关统计或内存文件的内存统计。 举例:jmap -heap 2960, jmap -histo 2960获取类相关的堆直方图,jmap -histo /usr/bin/java core(Attaching to core core from executable /usr/bin/java) jdb: 命令行调试器,它采用JDI(Java Debug Interface)发起或建立 到目标JVM的连接。举例:jdb -listconnectors 打印可用的连接器,jdb -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=9302, jdb -connect sun.jvm.hotspot.jdi.SACoreAttachingConnector:javaExecutable=
JAVAHOME/bin/javacore,jstack−m2117jhat:检测Java堆放并找出哪个对象占用最多空间,以及发现不再使用待未能释放的对象。jmap:打印运行的jvm内存相关统计或内存文件的内存统计。举例:jmap−heap2960,jmap−histo2960获取类相关的堆直方图,jmap−histo/usr/bin/javacore(Attachingtocorecorefromexecutable/usr/bin/java)jdb:命令行调试器,它采用JDI(JavaDebugInterface)发起或建立到目标JVM的连接。举例:jdb−listconnectors打印可用的连接器,jdb−connectsun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=9302,jdb−connectsun.jvm.hotspot.jdi.SACoreAttachingConnector:javaExecutable=JAVA_HOME/bin/java,core=core.20441,jsadebugd $JAVA_HOME/bin/java core.20441——start an SA debug server,
jdb -connect sun.jvm.hotspot.jdi.SADebugServerAttachingConnector:debugServerName=machine1
注意使能一些选项或标志以用来JVM定位和问题处理。比如:
(1)在启动程序前使能产生core文件,通过在Linux/Solairs界面,使用ulimit -c unlimited 足够;
(2)在JVM的标记中增加 -XX:+HeapDumpOnOutOfMemoryError ;
(3)持续运行Java飞行记录器(Java Flight Recording)——可以方便的处理内存泄露、网络故障、高CPU使用和线程阻塞等问题。
(4)在JVM的命令行中增加-verbosegc。verbosegc记录关于垃圾回收器的基本信息,包括是否垃圾回收运行很长时间、是否空闲内存随着时间在减少等,并循环记录日志,如从JDK7开始,可以使用 UseGClogFileRotation and NumberOfGCLogFiles 标记。
(5)定位或搜索问题前,打印java version和jvm标记。使用java -version命令或在jvm参数中增加 -XX+PrintCommandLineFlags and -showversion;
(6)建立JMX、JMC远程监控。在java程序运行起来后的阶段的话,也可以通过jcmd help ManagementAgent.start。
在程序出现问题后,记得在重启前收集相关信息,如core file或崩溃事件、hs_err打印java崩溃信息、日志、java堆、JFR,如果是程序停止响应,则还要收集:堆栈跟踪(jcmd Thread.print)