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

S0S1EOPYGCYGCTFGCFGCTGCT
58.370.0093.196.6958.21461.01072.0553.065

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

S0CS1CS0US1UECEUOCOUPCPUYGCYGCTFGCFGCTGCT
10432.010048.06089.30.0307200.0182057.6720896.048229.8144448.084077.9461.01072.0553.065
10432.010048.06089.30.0307200.0182314.8720896.048229.8144448.084077.9461.01072.0553.065
10432.010048.06089.30.0307200.0182330.7720896.048229.8144448.084077.9461.01072.0553.065
10432.010048.06089.30.0307200.0182682.4720896.048229.8144448.084077.9461.01072.0553.065
10432.010048.06089.30.0307200.0182692.1720896.048229.8144448.084077.9461.01072.0553.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<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等数据

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值