JVM探秘(四)-Java虚拟机性能监控工具详解

文章目录

    • 一、jps命令详解
      • 1.概述
      • 2.使用方法
      • 3.应用举例
    • 二、jstat命令详解
      • 1.概述
      • 2.使用方法
      • 3. 应用举例

一、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选项参数为
JVM探秘(四)-Java虚拟机性能监控工具详解_第1张图片

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的选项如图所示:
JVM探秘(四)-Java虚拟机性能监控工具详解_第2张图片

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{
     
    
}
  1. jstat -class vmid
    打开命令行窗口,先使用jps命令查出该程序的LVMID。
    在这里插入图片描述
    经查询可知该程序的LVMID为2800。
    在命令行工具中输入jstat -class 2800,得到的结果如下所示:
    在这里插入图片描述
  • Loaded:装载的类的数量
  • Bytes:装载类所占用的字节数
  • Unloaded:卸载类的数量
  • Bytes:卸载类的字节数
  • Time:装载和卸载类所花费的时间

在上述代码中,添加一行代码,如图所示:
JVM探秘(四)-Java虚拟机性能监控工具详解_第3张图片
在重新运行,重复上述步骤:
在这里插入图片描述
可以看到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查询:
在这里插入图片描述
我们可以看到,这个对象直接分配到了老年代,这是因为虚拟机的内存分配策略包含大对象直接进入老年代。具体细节我们在后续的博文中再详述。
本文未完待续。

你可能感兴趣的:(JVM,java,jvm)