Java bin 目录下的小工具使用与学习
结合周志明著的《深入理解Java虚拟机第三版》
JAVA与C++之间有一堵由内存动态分配和垃圾收集技术围成的高墙,墙外面的人想出去,墙里面的人却想出来。
首先需要注意的是:jdk安装好了之后,不是通过双击bin目录下的应用程序来使用的,是设置环境变量
JAVA_HOME=“jdk目录”,再在path环境变量后面追加%JAVA_HOME%\bin; 然后再直接在cmd里面使用相关命令,否则直接使用的的话会发生闪退的情况。
我使用的是JDK 15 采用的垃圾回收器是ZGC
jps:虚拟机进程状况工具
JVM Process Status Tool
选项 | 作用 |
---|---|
-q | 只输出LVMID,省略主类名称 |
-m | 输出虚拟机进程启动时传递给主类main()函数的参数 |
-v | 输出虚拟机进程启动时的JVM参数 |
-l | 输出主类的全名,如果进程执行的是jar包,输出jar包的路径 |
功能虽然比较单一,但是使用的频率是很高的,因为需要根据此来获取LVMID以供其他的工具使用.
使用的格式:在cmd中 jps [optins] [hostid]
实例分析与使用:
我打开了一个java程序,程序处于运行状态:
然后打开任务管理器:
可以看到在我的任务管理器中,有两个java程序在运行?分别有自己的PID。接下来我使用jps:
9384是jar包在执行,8284是我开启的程序。
jstat:虚拟机统计信息监视工具
介绍:jstat(JVM Statistics Monitoring Tool)是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类加载、内存、垃圾收集、即时编译等运行时数据,在没有GUI的图形界面,只提供纯文本控制台环境的服务器上,它将是运行期定位虚拟机问题所在的常用工具。
命令格式:jstat [option vmid [interval[s|ms] [count] ] ]
对于本地的虚拟机进程,VMID与LVMID是一致的;如果是远程虚拟机进程,那么,LVMID的格式如下:
[protocol:][//]lvmid[@hostname[:port]/servername]
参数interval和count代表查询间隔和次数,如果省略这两个参数,代表只查询一次。
eg:jstat -gc 2764 250 20
代表没250毫秒查询一次进程2764的垃圾收集状况,一共查询20次。
jstat主要针对检测:垃圾回收 类加载 运行期编译。
jstat工具主要选项:
选项 | 作用 |
---|---|
-class | 监视类加载、类卸载、总空间以及类装载所耗费的时间 |
-gc | 监视java堆的情况,包括Eden区,两个Survivor、老年代、永久代等的容量,已用空间、垃圾收集时间合计 |
-gcutil | 与gc内容基本相同,单输出主要关注于已经使用的空间占总空间的百分比 |
-gacapacity | 与-gc内容基本相同,但是主要关注Java堆各个区域使用到的最大最小空间 |
-gccause | 与-gcutil功能一样,但是会输出导致上一次垃圾收集产生的原因 |
–gcnew | 监视新生代垃圾收集情况 |
-gcnewcapacity | 监视内容与-gcnew相同,主要关注使用到的最大最小空间 |
–gcold | 监视新生代垃圾收集情况 |
-gcoldcapacity | 监视内容与-gcnew相同,主要关注使用到的最大最小空间 |
-complier | 输出即时编译器编译过的方法、耗时等信息 |
-printcompilation | 输出已经被编译的方法 |
随便写创建一个创建对象的程序如下:
package JVM学习样例;import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class Main2 {static class TestClass{private byte[] bytes=new byte[64*1024];
}public static void main(String[] args) throws InterruptedException {while (true){new Main.TestClass();}}
}
开始执行程序 并且使用jstat检测堆的情况:
S0 S1分别代表survivor0 1 E带表Eden空间占用百分比 O代表老年代空间占用百分比 M YGC代表垃圾回收次数 TGCT表示新生代垃圾回收使用时间 FGC表示发生Full GC的次数 FGCT 代表FGC垃圾回收占用的时间 GCT表示垃圾回收一共耗时。对于O M CGC CGCT目前先不做研究。
由于我的代码没有加sleep停顿,因此产生的速度过快,在我使用jstat的时候 可以看到新生代的垃圾回收次数因为程序产生数据过多,发生了很多次了已经,Eden会接近饱和状态,在垃圾回收的功能下,一直释放空间,随着程序的运行,一直被填充,然后回收。
总结:虽然使用jstat不如可视化工具表现得那样直观,但是在实际的生产环境中可能不一定能够使用图像界面,服务器大多数管理员习惯了在文本控制台工作,直接使用jstat仍然是常用的监控方式。
jinfo:Java配置信息工具
jinfo可以用于实时查看和调整虚拟机各项参数。使用jps命令的-v可以获取虚拟机启动时显式指定的参数列表,但如果想知道未被显式指定的参数的系统默认值,除了去查找资料以外,就只能使用jinfo的-flag选项进行查询了(如果使用的是JDK6以上的版本可以使用java -XX:+PrintFlagsFinal查看参数默认值也是一个很好的选择)。jinfo还可以使用-sysprops选项把虚拟机进程的System.getProperties()打印出来,这个命令在JDK 5时期已经随着Linux版的JDK发布,当时只提供了信息查询的功能,JDK6以后,jinfo在Windows和Linux平台都有提供,并且家去了在运行期修改部分参数的能力(-flag [+|-]name,或者-flag [+|-]name=value),在JDK6中,jinfo对于Windows平台功能仍有较大的限制,只是提供了最基本的-flag选项,
jmap:Java内存映像工具
jmap用于生成堆转储快照(一般称为heapdump或者dump文件)。如果不使用jmap命令,想要获取Java堆转储快照,可以使用一些比较暴力的手段,比如说-XX:+HeapDumpOnOutOfMemoryError参数,可以让虚拟机在内存溢出异常出现之后自动生成堆转储快照文件,通过-XX:+HeapDumpOnCtrlBreak参数可以使用Ctrl+Break键让虚拟机生成堆转储快照文件,又或者在Linux系统下通过Kill -3命令发送进程退出信号“恐吓”一下虚拟机,也可以顺利拿到堆转储快照。
jamp不仅可以用于生成堆转储快照文件,还可以查询finalize执行队列、Java堆和方法区详细信息,如空间使用率、当前用的是哪种收集器等。
jmap命令格式:
jamp [option] vmid
如下表为jamp的主要选项与作用:
选项 | 作用 |
---|---|
-dump | 生成堆转储快照。格式为-dump:[live,]format=n,file=< filename>, 其中live子参数说明是否只dump出存活对象 |
-finalizerinfo | 显示在F-Queue中等待Finalizer线程执行finalize方法的对象。只在Linux/Solaris平台下有效 |
-heap | 显示Java堆的详细信息,如使用哪种垃圾回收器、参数配置、分代状况等。只在Linux/Solaris平台下有效 |
-histo | 显示堆中对象的统计信息、包括类、实例数量、合计容量等 |
-permstat | 以ClassLoader为统计口径显示永久代的内存状态。只在Linux/Solaris中有效 |
-F | 当虚拟机进程对-dump选项没有响应的时候,可以使用这个选项强制生成堆转储快照。只在Linux/Solaris中有效 |
如下使用jmap命令生成一个堆转储快照。首先代码如下:
package JVM学习样例;import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class Main2 {static class TestClass{private byte[] bytes=new byte[64*1024];
}public static void main(String[] args) throws InterruptedException {while (true){Thread.sleep(2000);new Main.TestClass();}}
}
如图可以看到生成了名字为haha.bin的堆转储快照。由于我的路径中有中文,所以显示的信息中会有问号,但是可以看到它确实已经生成了。
可以看到在于src同级目录下生成了这个文件。接下来我们首先使用jhat来分析我们刚刚生成的这个文件
jhat:虚拟机堆转储快照分析工具
在JDK9中这个工具已经被移除了。
JDK提供jhat与jmap搭配使用,用于分析jmap生成的堆转储快照。jhat内置了一个微型的HTTP/Web服务器,生成堆转储快照的分析结果侯,可以在浏览器中查看。不过实事求是的说,除非手头没有别的工具了,否则不建议使用这个工具。原因体现在两个方面:
- 一般情况下是不会在部署应用程序的服务器上直接分析堆转储快照的,即使可以这样做,也会想办法把堆转储快照转移到别的机器上面分析,因为分析堆转储快照是一个耗时耗费资源的过程因此不建议这样做,既然都要在别的机器上运行,就不必受命令行工具限制了,在别的机器上使用高级的工具便可以。
- jhat分析相对来说简陋,后面将会介绍到VisualVM等工具都比jhat功能强大。
在低于JDK9的版本中可以如下命令进行分析快照:
jhat haha.bin
在显示Server is ready以后用火狐在浏览器中输入https://localhost:7000/可以看到分析结果。分析结果默认以包为单位进行显示,分析内存泄露问题主要会使用到其中的“Heap Histogram”与OQL页签的功能,前者可以找到内存中总容量最大的对象,后者是标准的对象查询语言。
jstack:Java堆栈跟踪工具
jstack(Stack Trace Of Java)命令用于生成虚拟机当前时刻的线程快照,一般称为threaddump或者javacore。线程快照就是当前虚拟机每一条线程正在执行的方法堆栈的集合,生成线程快照来查看各个现成的调用堆栈,就可以知道线程是处于死循环?等待那一部分的资源?死锁?
jstack命令格式:
jstack [option] vmid
jstack工具的主要选项如下:
选项 | 作用 |
---|---|
-F | 当正常输出的请求不被响应的时候,强制输出线程堆栈 |
-l |
除了堆栈以外,显示
Java bin 目录下的小工具使用与学习相关推荐
最新文章
热门文章 |