JVM常用工具

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情况

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

(2)jstat -gc 19508 1000 5 每隔1000毫秒即每隔1秒,总共收集5次GC情况

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

(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应用程序,模拟问题

import java.util.List;
import java.util.ArrayList;
public class Test {
    public static void main(String[] args){
        List list = new ArrayList();
        // 不停的构造新的对象,且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,JVM相关)