跳转至

JDK的命令行工具

1. jps:虚拟机进程状况工具

功能:列出正在运行的虚拟机进程,并显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一ID(LVMID)

命令格式: jps [ options ] [hostid]

2. jstat:虚拟机统计信息监视工具

命令格式: jstat [ option vmid [intervals[s|ms] [count]]]

如果是本地虚拟机进程,VMID与LVMID是一致的,如果是远程虚拟机进程,那VMID的格式应当是:

[protocal:][//]lvmid[@hostname[:port]]/servername

参数interval和count代表查询间隔和次数,如果省略这两个参数,说明只查询一次。 假设需要每250毫秒查询一次进程2764垃圾收集状况,一共查询20次,命令:

jstat -gc 2764 250 20

选项 option 代表着用户希望查询的虚拟机信息,主要分为3类:类加载、垃圾收集、运行期编译状况。

3. jinfo:Java配置信息工具

jinfo(Configuration Info for Java)的作用是实时地查看和调整虚拟机各项参数。

命令格式: jinfo [ option ]pid

4. jmap:Java内存映像工具

jmap(Memory Map for Java)命令用于生成堆转储快照(一般称为headump或dump文件)。

jmap的作用并不仅仅是为了获取dump文件,它还可以查询finalize执行队列,Java堆和永久代的详细信息,如空间使用率、当前用的是哪种收集器等。

命令格式: jmap [ option ] vmid

5. jhat:虚拟机堆转储快照分析工具

Sun JDK提供了jhat(JVM Heap Analysis Tool)命令与jmap搭配使用,来分析生成的堆转储快照。

6. jstack:Java堆栈跟踪工具

jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待都是导致线程长时间停顿的常见原因。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做些什么事情,或者等待什么资源。

jstack命令格式:

jstack [ option ] vmid

在JDK 1.5 中,java.lang.Thread类新增了一个getAllStackTraces()方法用于获取虚拟机中所有线程的StackTraceElement对象。使用这个方法可以通过简单的几行代码就完成jstack的大部分功能,在实际项目中不放调用这个方法做个管理员页面,可以随时使用浏览器来查看线程堆栈。

<%@ page import="java.util.Map" %><%--
  Created by IntelliJ IDEA.
  User: zhaijiayu
  Date: 2020/3/6
  Time: 11:29
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>服务器线程信息</title>
  </head>
  <body>
  <pre>
    <%
      for(Map.Entry<Thread, StackTraceElement[]> stackTrace : Thread.getAllStackTraces().entrySet()){
        Thread thread = (Thread) stackTrace.getKey();
        StackTraceElement[] stack = (StackTraceElement[]) stackTrace.getValue();
        if(thread.equals(Thread.currentThread())){
          continue;
        }
        out.print("\n线程: " + thread.getName() + "\n");
        for(StackTraceElement element : stack){
          out.print("\t" + element + "\n");
        }
      }
    %>
  </pre>
  </body>
</html>

7. HSDIS:JIT生成代码反汇编

在Java虚拟机规范中,详细描述了虚拟机指令集中每条指令的执行过程、执行前后堆操作数栈、局部变量表的影响等细节。随着技术的发展,高性能虚拟机真正的细节实现方式已经渐渐与虚拟机规范所描述的内容产生了越来越大的差距,虚拟机规范中的描述逐渐成了虚拟机实现的“概念模型”——即实现只能保证规范描述等效。基于这个原因,我们分析程序的执行语义问题时,在字节码层面上分析完全可行,但分析程序的执行行为问题时,字节码层面上分析就没有意义了,需要通过其他方式解决。

分析程序如何执行,通过软件调试工具(GDB, Windbg等)来断点调试是最常见的手段,但是这样的调试方式在Java虚拟机中会遇到很大的困难,因为大量执行代码是通过JIT编译器动态生成到CodeBuffer中的,没有很简单的手段来处理这种混合模式的调试。因此,不得不通过一些特别的手段来解决问题,基于这种背景,HSDIS插件就正式登场了。

HSDIS是一个Sun官方推荐的HotSpot虚拟机JIT编译代码的反汇编插件,它包含在HotSpot虚拟机的源码中,但没有提供编译后的程序。它的作用是让HotSpot的-XX:+PrintAssembly指令调用它来把动态生成的本地代码还原为汇编代码输出,同时还生成了大量非常有价值的注释,这样我们就可以通过输出的代码分析问题。