在Java JDK的安用装目录bin下,有一些有非常实用的小工具,可用于分析JVM初始配置、内存溢出异常等问题,我们接下来将对些常用的工具进行一些说明。
JDK小工具简介
在JDK的bin目录下面有一些小工具,如javac、jar、jstack、jstat等,在日常编译运行过程中有着不少的“额外”功能,那么它们是怎么工作的呢?虽然这些文件本身已经被编译成可执行二进制文件了,但是其实它们的功能都是由tools.jar这个工具包(配合一些dll或者so本地库)完成的,每个可执行文件都对应一个包含main函数入口的java类(有兴趣可以阅读openJDK相关的源码(时代Java的JDK8/Java8源码在线阅读),它们的对应关系如下(更多可去openJDK查阅):
javac com.sun.tools.javac.Main
jar sun.tools.jar.Main
jps sun.tools.jps.Jps
jstat sun.tools.jstat.Jstat
jstack sun.tools.jstack.JStack
...
工具/命令简要说明
javac - Java代码编译命令。
jar - 打包工具命令。
jstack - 查看和跟踪Java堆栈信息的工具。
jstat - 于监控虚拟机各种运行状态信息。
tools.jar的使用
我们一般开发机器上都会安装JDK+jre,这时候,要用这些工具,直接运行二进制可执行文件就行了,但是有时候,机器上只有jre而没有JDK,我们就无法用了么?
如果你知道如上的对应关系的话,我们就可以"构造"出这些工具来(当然也可以把JDK安装一遍,本篇只是介绍另一种选择),比如我们编写
//Hello.java
public class Hello{
public static void main(String[] args)throws Exception{
while(true){
test1();
Thread.sleep(1000L);
}
}
public static void test1(){
test2();
}
public static void test2(){
System.out.println("invoke test2");
}
}
可以验证如下功能转换关系
1.编译源文件:
javac Hello.java => java -cp tools.jar com.sun.tools.javac.Main Hello.java
结果一样,都可以生成Hello.class文件
然后我们开始运行java -cp . Hello
2.查看java进程:
jps => java -cp tools.jar sun.tools.jps.Jps
结果一样,如下:
4615 Jps
11048 jar
3003 Hello
3.jstat动态查看内存:
jstat -gcutil 3003 100 3 => java -cp tools.jar sun.tools.jstat.Jstat -gcutil 3003 100 3
发现结果是一样的
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 4.00 0.00 17.42 19.65 0 0.000 0 0.000 0.000
0.00 0.00 4.00 0.00 17.42 19.65 0 0.000 0 0.000 0.000
0.00 0.00 4.00 0.00 17.42 19.65 0 0.000 0 0.000 0.000
4.查看当前运行栈信息
正常情况,执行如下命令结果也是一样,可以正常输出
jstack 3003 =》 java -cp tools.jar sun.tools.jstack.JStack 3003
但是有的jre安装不正常的时候,会报如下错误
Exception in thread "main" java.lang.UnsatisfiedLinkError: no attach in java.library.path
这是因为jstack的运行需要attach本地库的支持,我们需要在系统变量里面配置上其路径,假如路径为/home/JDK/jre/bin/libattach.so
命令转换成
jstack 3003 =》 java -Djava.library.path=/home/JDK/jre/bin -cp tools.jar sun.tools.jstack.JStack 3003
就可以实现了
在linux系统中是libattach.so,而在windows系统中是attach.dll,它提供了一个与本机jvm通信的能力,利用它可以与本地的jvm进行通信,许多java小工具就可能通过它来获取jvm运行时状态,也可以对jvm执行一些操作。
jstack命令详解
jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",
Windows的jstack使用方式只支持以下的这种方式:jstack [-l] pid
如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。
需要注意的问题:
l 不同的 JAVA虚机的线程 DUMP的创建方法和文件格式是不一样的,不同的 JVM版本, dump信息也有差别。
l 在实际运行中,往往一次 dump的信息,还不足以确认问题。建议产生三次 dump信息,如果每次 dump都指向同一个问题,我们才确定问题的典型性。
2、命令格式
$jstack [ option ] pid
$jstack [ option ] executable core
$jstack [ option ] [server-id@]remote-hostname-or-IP
参数说明:
pid: java应用程序的进程号,一般可以通过jps来获得;
executable:产生core dump的java可执行程序;
core:打印出的core文件;
remote-hostname-or-ip:远程debug服务器的名称或IP;
server-id: 唯一id,假如一台主机上多个远程debug服务;
--
知识分享,时代前行!~~ 时代Java还有更多好文章……请查看历史文章和官网,有分享,有收获!