JVM常用工具
2015-10-29 23:32
316 查看
jps: 查找当前虚拟机进程
(1)jps -m 列出当前虚拟机进程以及传给虚拟机启动主进程main方法的参数
(2)jps -l 输出主类的名称
(3)jps -v 输出虚拟机启动参数
(4)jps -q 只输出虚拟机进程号
jinfo: 查看和调整JVM参数
(1)jinfo [option选项] [PID JVM进程]
(2)jinfo -flag [JVM参数名称] [PID]
比如 jinfo -flag NewSize 19508 会打印出来 -XX:NewSize 即新生代内存配置的参数
(3)jinfo -flag +[JVM参数名称] [PID] 使该项参数生效
(4)jinfo -flag -[JVM参数名称] [PID] 禁用该项参数
比如 jinfo -flag -NewSize 19508 禁用新生代内存配置项,当然这个配置项是不允许的,会报错:
Exception in thread “main” com.sun.tools.attach.AttachOperationFailedException: flag ‘NewSize’ cannot be changed
(5)jinfo -flag [JVM参数名称]=[参数的值]
比如 jinfo -flag NewSize=5570560 注意单位是Byte,不是M,当然这个配置项也是不允许设置的~~~
jstat监视JVM运行状态,比如类装载、GC等数据
先通过jsp或者ps aux|grep java 命令获得jvm进程号,比如是 19508
(1)jstat -gcutil 19508 输出当前JVM的GC情况
(2)jstat -gc 19508 1000 5 每隔1000毫秒即每隔1秒,总共收集5次GC情况
(3)S 代表Survivor区,E代表Eden区,P代表Permanent区,O代表Old区,如下
S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
EC:年轻代中Eden(伊甸园)的容量 (字节)
EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
OC:Old代的容量 (字节)
OU:Old代目前已使用空间 (字节)
PC:Perm(持久代)的容量 (字节)
PU:Perm(持久代)目前已使用空间 (字节)
YGC:从应用程序启动到采样时年轻代中gc次数
YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
FGC:从应用程序启动到采样时old代(全gc)gc次数
FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)
NGCMN:年轻代(young)中初始化(最小)的大小 (字节)
NGCMX:年轻代(young)的最大容量 (字节)
NGC:年轻代(young)中当前的容量 (字节)
OGCMN:old代中初始化(最小)的大小 (字节)
OGCMX:old代的最大容量 (字节)
OGC:old代当前新生成的容量 (字节)
PGCMN:perm代中初始化(最小)的大小 (字节)
PGCMX:perm代的最大容量 (字节)
PGC:perm代当前新生成的容量 (字节)
S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E:年轻代中Eden(伊甸园)已使用的占当前容量百分比
O:old代已使用的占当前容量百分比
P:perm代已使用的占当前容量百分比
S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节)
S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节)
ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)
DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满)
TT: 持有次数限制
MTT : 最大持有次数限制
jstack监视JVM线程堆栈情况,排查问题首选工具
jstack [option] PID
可用选项包括:
jstack -l PID 除了堆栈,显示关于锁的附加信息
jstack -m PID 开启mixd mode 即混合模式,还会打印C/C++堆栈
jstack -F PID 如果jstack正常请求没有想学习,强制输出线程堆栈
(1)比如JVM进程号是 4834,那么 jstack 4834 会打印出整个JVM堆栈
(2)如果想要保存堆栈信息,可以输出到一个文件,比如 jstack 4834 > javacore.txt
请仔细看看堆栈内容
模拟一个线上故障,使用jstack来定位问题
(1)写一段简单代码,启动Java应用程序,模拟问题
(2)查找JVM进程号
第一种方式:jps 直接找到进程号,比如是 4834
第二种方式:ps -ef | grep java ,也能找到JVM进程号,比如 4834
(3)定位当前JVM中最耗时、最耗CPU、最耗内存的Java线程
这里要结合top命令来使用:
top -Hp PID 本例中,即 top -Hp 4834 则会进入top控制台,并且追踪的是当前JVM
在这个控制台,可以根据 T(时间)、P(CPU)、M(内存) 来排序
比如本例中,就是要找最耗时的Java线程,那么在top控制台,直接输入大写字母 T ,即根据时间来排序
得到最耗时的Java线程号,比如是 4835
如果你直接使用 jstack 命令查看过Java堆栈信息,会发现每一个线程都是用十六进制标识的
因此,使用 printf “%x\n” 4835 将当前线程号转成十六进制,得到 12e3
最后:jstack PID | grep 线程号 本例中即 jstack 4834 | grep 12e3
在JDK6以上,比如JDK8环境,那么打印出来的是:
在JDK6环境,打印出来的,则直接定位到 Test.java 的main方法
jstat监视JVM运行状态,比如类装载、GC等数据
(1)jps -m 列出当前虚拟机进程以及传给虚拟机启动主进程main方法的参数
(2)jps -l 输出主类的名称
(3)jps -v 输出虚拟机启动参数
(4)jps -q 只输出虚拟机进程号
jinfo: 查看和调整JVM参数
(1)jinfo [option选项] [PID JVM进程]
(2)jinfo -flag [JVM参数名称] [PID]
比如 jinfo -flag NewSize 19508 会打印出来 -XX:NewSize 即新生代内存配置的参数
(3)jinfo -flag +[JVM参数名称] [PID] 使该项参数生效
(4)jinfo -flag -[JVM参数名称] [PID] 禁用该项参数
比如 jinfo -flag -NewSize 19508 禁用新生代内存配置项,当然这个配置项是不允许的,会报错:
Exception in thread “main” com.sun.tools.attach.AttachOperationFailedException: flag ‘NewSize’ cannot be changed
(5)jinfo -flag [JVM参数名称]=[参数的值]
比如 jinfo -flag NewSize=5570560 注意单位是Byte,不是M,当然这个配置项也是不允许设置的~~~
jstat监视JVM运行状态,比如类装载、GC等数据
先通过jsp或者ps aux|grep java 命令获得jvm进程号,比如是 19508
(1)jstat -gcutil 19508 输出当前JVM的GC情况
S0 | S1 | E | O | P | YGC | YGCT | FGC | FGCT | GCT |
---|---|---|---|---|---|---|---|---|---|
58.37 | 0.00 | 93.19 | 6.69 | 58.21 | 46 | 1.010 | 7 | 2.055 | 3.065 |
S0C | S1C | S0U | S1U | EC | EU | OC | OU | PC | PU | YGC | YGCT | FGC | FGCT | GCT |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
10432.0 | 10048.0 | 6089.3 | 0.0 | 307200.0 | 182057.6 | 720896.0 | 48229.8 | 144448.0 | 84077.9 | 46 | 1.010 | 7 | 2.055 | 3.065 |
10432.0 | 10048.0 | 6089.3 | 0.0 | 307200.0 | 182314.8 | 720896.0 | 48229.8 | 144448.0 | 84077.9 | 46 | 1.010 | 7 | 2.055 | 3.065 |
10432.0 | 10048.0 | 6089.3 | 0.0 | 307200.0 | 182330.7 | 720896.0 | 48229.8 | 144448.0 | 84077.9 | 46 | 1.010 | 7 | 2.055 | 3.065 |
10432.0 | 10048.0 | 6089.3 | 0.0 | 307200.0 | 182682.4 | 720896.0 | 48229.8 | 144448.0 | 84077.9 | 46 | 1.010 | 7 | 2.055 | 3.065 |
10432.0 | 10048.0 | 6089.3 | 0.0 | 307200.0 | 182692.1 | 720896.0 | 48229.8 | 144448.0 | 84077.9 | 46 | 1.010 | 7 | 2.055 | 3.065 |
S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
EC:年轻代中Eden(伊甸园)的容量 (字节)
EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
OC:Old代的容量 (字节)
OU:Old代目前已使用空间 (字节)
PC:Perm(持久代)的容量 (字节)
PU:Perm(持久代)目前已使用空间 (字节)
YGC:从应用程序启动到采样时年轻代中gc次数
YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
FGC:从应用程序启动到采样时old代(全gc)gc次数
FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)
NGCMN:年轻代(young)中初始化(最小)的大小 (字节)
NGCMX:年轻代(young)的最大容量 (字节)
NGC:年轻代(young)中当前的容量 (字节)
OGCMN:old代中初始化(最小)的大小 (字节)
OGCMX:old代的最大容量 (字节)
OGC:old代当前新生成的容量 (字节)
PGCMN:perm代中初始化(最小)的大小 (字节)
PGCMX:perm代的最大容量 (字节)
PGC:perm代当前新生成的容量 (字节)
S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E:年轻代中Eden(伊甸园)已使用的占当前容量百分比
O:old代已使用的占当前容量百分比
P:perm代已使用的占当前容量百分比
S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节)
S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节)
ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)
DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满)
TT: 持有次数限制
MTT : 最大持有次数限制
jstack监视JVM线程堆栈情况,排查问题首选工具
jstack [option] PID
可用选项包括:
jstack -l PID 除了堆栈,显示关于锁的附加信息
jstack -m PID 开启mixd mode 即混合模式,还会打印C/C++堆栈
jstack -F PID 如果jstack正常请求没有想学习,强制输出线程堆栈
(1)比如JVM进程号是 4834,那么 jstack 4834 会打印出整个JVM堆栈
(2)如果想要保存堆栈信息,可以输出到一个文件,比如 jstack 4834 > javacore.txt
请仔细看看堆栈内容
模拟一个线上故障,使用jstack来定位问题
(1)写一段简单代码,启动Java应用程序,模拟问题
import java.util.List; import java.util.ArrayList; public class Test { public static void main(String[] args){ List<User> list = new ArrayList<User>(); // 不停的构造新的对象,且main方法运行后,该线程就一直不会停止 // 对于整个JVM应用程序来说,由于就模拟了这一个线程,因此肯定是最耗时的线程 while(true){ User u = new User(); list.add(u); try{ System.out.println("size:" + list.size()); Thread.sleep(200); }catch(Exception e){ } } } public static class User { private byte[] bytes = new byte[1024]; } }
(2)查找JVM进程号
第一种方式:jps 直接找到进程号,比如是 4834
第二种方式:ps -ef | grep java ,也能找到JVM进程号,比如 4834
(3)定位当前JVM中最耗时、最耗CPU、最耗内存的Java线程
这里要结合top命令来使用:
top -Hp PID 本例中,即 top -Hp 4834 则会进入top控制台,并且追踪的是当前JVM
在这个控制台,可以根据 T(时间)、P(CPU)、M(内存) 来排序
比如本例中,就是要找最耗时的Java线程,那么在top控制台,直接输入大写字母 T ,即根据时间来排序
得到最耗时的Java线程号,比如是 4835
如果你直接使用 jstack 命令查看过Java堆栈信息,会发现每一个线程都是用十六进制标识的
因此,使用 printf “%x\n” 4835 将当前线程号转成十六进制,得到 12e3
最后:jstack PID | grep 线程号 本例中即 jstack 4834 | grep 12e3
在JDK6以上,比如JDK8环境,那么打印出来的是:
"main" #1 prio=5 os_prio=0 tid=0xb6907000 nid=0x12e3 waiting on condition [0xb6aa1000]
在JDK6环境,打印出来的,则直接定位到 Test.java 的main方法
"Thread-Test" prio=5 os_prio=0 tid=0xb6907000 nid=0x12e3 waiting on condition [0xb6aa1000]
jstat监视JVM运行状态,比如类装载、GC等数据
相关文章推荐
- Java 6 JVM参数选项大全(中文版)
- Java虚拟机JVM性能优化(二):编译器
- Java程序员必须知道的5个JVM命令行标志
- Java虚拟机JVM性能优化(三):垃圾收集详解
- JAVA中JVM的重排序详细介绍
- Java虚拟机JVM性能优化(一):JVM知识总结
- Android Studio 报错failed to create jvm error code -4的解决方法
- 解析Linux系统中JVM内存2GB上限的详解
- Groovy Meta Object Protocol
- xms/xmx/xss在kette中的调优设置
- JVM工作原理和特点
- JVM性能调优监控工具jps、jstack、jstat、jmap、jinfo使用详解
- jmap详解
- 深入Java虚拟机
- JVM内存模型及垃圾收集策略解析
- JVM内存配置详解
- 关于String与StringBuilder的提问与总结
- 亮剑JVM的9款编程语言杀手开发利器重磅推荐
- JVM的监控与优化