一、jps命令详解
1.概述
jps(JVM Process Status Tool):可以列出正在运行的虚拟机进 程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一 ID(LVMID,Local Virtual Machine Identifier)。LVMID即虚拟机实例运行时的进程号,比如我们同时运行三个Java程序,那么将会有与之对应的三个Java虚拟机实例,每一个虚拟机实例都有一个ID标识符。
2.使用方法
jps的命令格式如下:
jps [ options ] [ hostid ]
options:命令选项,用来对输出格式进行控制
hostid:指定特定主机,可以是ip地址和域名, 也可以指定具体协议,端口。格式为:[protocol:][[//]hostname][:port][/servername]
关于jps命令options选项参数为
3.应用举例
我们运行如下代码
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Test {
public static void main(String[] args) {
try{
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(8000));
Socket accept = serverSocket.accept();
System.out.println("收到客户端连接.....");
}catch (Exception e){
e.printStackTrace();
}
}
}
改代码启动一个ServerSocket等待一个客户端连接,由于accpet是阻塞方法,那么在未收到客户端连接时,不会退出阻塞,以便我们进行测试。现在我们打开命令行窗口,输入jps -l命令:
可以看到,jps显示我们运行程序的LVMID以及对应的包含报名的主类名称。
上述参数都比较简单,读者可自行尝试其他options参数。
使用jsp -m则不会显示包名。如图所示:
二、jstat命令详解
1.概述
jstat(JVM Statistics Monitoring Tool)是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程 [1] 虚拟机进程中的类加载、内存、垃圾收集、即时编译等运行时数据。它是Java虚拟机性能监控的常用工具。
2.使用方法
jstat命令格式为:
jstat [ option vmid [interval[s|ms] [count]] ]
如果是本地虚拟机进程,VMID与LVMID是一致的;如果是远程虚拟机进程,那VMID的格式应当是:[protocol:][//]lvmid[@hostname[:port]/servername]
参数interval和count代表查询间隔和次数,如果省略这2个参数,说明只查询一次。在下文中我们会演示该参数。其中关于选项options的选项如图所示:
3. 应用举例
我们执行如下代码:
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Test01 {
public static void main(String[] args) {
try{
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(8000));
Socket accept = serverSocket.accept();
System.out.println("收到客户端连接.....");
}catch (Exception e){
e.printStackTrace();
}
}
}
class Person{
}
- jstat -class vmid
打开命令行窗口,先使用jps命令查出该程序的LVMID。
经查询可知该程序的LVMID为2800。
在命令行工具中输入jstat -class 2800,得到的结果如下所示:
- Loaded:装载的类的数量
- Bytes:装载类所占用的字节数
- Unloaded:卸载类的数量
- Bytes:卸载类的字节数
- Time:装载和卸载类所花费的时间
在上述代码中,添加一行代码,如图所示:
在重新运行,重复上述步骤:
可以看到Loaded的数量增加了1。是因为虚拟机在执行new指令时,会去加载Person类。
2. jstat -gc vmid
仍然运行上述代码,执行jstat -gc vmid 命令,得到的结果如下所示:
- S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C :年轻代中第二个survivor(幸存区)的容量 (字节)
- S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
- S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
- EC:年轻代中Eden(伊甸园)的容量 (字节)
- EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
- OC 老年代的容量 (字节)
- OU:老年代代目前已使用空间 (字节)
- PC:Perm(持久代)的容量 (字节)
- PU:Perm(持久代)目前已使用空间 (字节)
- YGC:从应用程序启动到采样时年轻代中gc次数
- YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
- FGC:从应用程序启动到采样时老年代代(全gc)gc次数
- FGCT:从应用程序启动到采样时老年代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
从上述图片可以看出,EC的总容量为130048K,已经使用了5201.9K。我们添加如下代码:
我们在通过jps命令先查出LVMID,在使用jstat命令,得到如下结果:
可以看到,60*1024+5201正好与66642相近。我们创建了一个60M的数组,它分配在了新生代。我们还可以持续监视变化,执行如下命令:
该命令的含义为:每个250毫秒检测一次,一共循环20次。
我们再次修改代码为:
在使用jstat查询:
我们可以看到,这个对象直接分配到了老年代,这是因为虚拟机的内存分配策略包含大对象直接进入老年代。具体细节我们在后续的博文中再详述。
三、jmap命令
1、概述
jmap(Memory Map for Java)命令用于生成堆转储快照。堆转储是反应Java堆使用情况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。 一般,在内存不足、GC异常等情况下,这个时候我们就可以制作堆Dump来查看具体情况,分析原因。
2、使用方法
jmap的命令格式为:
jmap [ option ] vmid
其中option选项如图所示:
3、应用举例
我们运行如下程序:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<byte[]> list = new ArrayList<byte[]>();
while(true){
if(list.size() <20){
list.add(new byte[1024*1024*5]);
try{
Thread.sleep(2000);
}catch (Exception e){
}
}else{
break;
}
}
try{
Thread.sleep(300000);
}catch (Exception e){
}
}
}
该程序是每隔两秒向arrayList中添加一个5M的字节数组。一共添加20个,当添加完毕后,休眠五分钟,之后程序退出。
执行程序后,我们使用jps找到该程序的LVMID。如图所示:
之后,使用jstat命令每隔两秒检测内存变化:
jstat -gc 16620 2000
从图中我们可以看到EU的所占的容量在不断的增长。待增长平稳后,我们新开一个命令行窗口运行jamp命令。
jmap -dump:format=b,file=Test.bin 16620
之后,该命令会生成Test.bin文件,这个文件可以用jvisualvm.exe程序打开,该程序在jps、jstat等工具的同级目录下:jdk1.8.0_91\bin。
打开该工具后,点击左上角的文件->装入,选择刚刚生成的文件。
我们从图中可以发现,byte[]类型的数组占据了在生成dump文件时刻,堆空间的97.8%。这时我们就应该去检查自己的程序,在哪个地方不断的产生对象填充到堆空间。其余命令读者可自行尝试。
本文未完待续。