JDK的监控和故障处理

发布于 2021-03-13  551 次阅读


JRE和JDK的区别是什么?

JRE:Java Runtime Environment

JDK:Java Development Kit

JRE顾名思义是Java运行时环境,包含了Java虚拟机,java基础类库;是用java语言编写的程序运行所需要的运行环境,是提供给想运行java程序的用户使用的;

JDK顾名思义是Java开发工具包,是程序员使用Java语言编写Java程序所需的开发工具包, 是提供给程序员使用的;JDK包含了JRE,同时还包含了编译Java源码的编辑器Javac,还包含了很多java程序调试和分析的工具:jconsole,jvisualvm等工具软件,还包含了java程序编写所需的 文档和demo例子程序;

如果需要运行java程序,只需要安装JRE;

如果需要编写java程序,需要安装JDK;

你写好的java源代码需要先编译,把.java文件中的源代码编译成.class文件的机器码,然后jre运行这些机器码,这就是从java代码变成可运行的程序的过程,一般打包好的java可运行程序都是编译过的,所以只需要jre就能直接运行,但是你自己开发的话写的都是java源代码,需要先编译才能用jre运行,所以你开发完需要用jdk中的编译器编译一次才能运行;(一次编译到处运行);

 

JDK命令行工具

这些命令在JDK安装目录下的bin目录下:

jps(JVM Process Status):类似于UNIX的PS命令;用户查看所有Java进程的启动类,传入参数和Java虚拟机参数等信息;

jstat(JVM Statics Monitoring Tool):用于收集HotSpot虚拟机各方面的运行数据;

jinfo(Configuration Info for Java):显示虚拟机配置信息;

jmap(JVM Heap Dump Browser):生成堆转储快照;

jhat(JVM Heap Dump Browser):用于分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户可以在浏览器上查看分析结构;

jstack(Stack Trace for Java):生成虚拟机当前时刻的线程快照,线程快照就是当前虚拟机内没有提奥线程正在执行的方法堆栈的集合;

 

jps:查看所有Java进程

jps(JVM Process Status)命令类似UNIX的ps命令

jps:显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一ID;jps -q:只输出进程的本地虚拟机唯一ID;

jps -l:输出主类的全名,如果进程之心的是Jar包,输出Jar路径;

jps -v:输出虚拟机进程启动时JVM参数;

jps -m:输出传递给Java进程main()函数的参数;

 

jstat:监视虚拟机各种运行状态信息

jstat(JVM Statics Monitoring Tool)适用于监视虚拟机各种运行状态信息的命令行工具,它可以显示本地或者远程(需要远程提供RMI支持)虚拟机进程中的类信息、内存、垃圾收集、JIT编译(即时编译)等运行数据,在没有GUI,只提供了纯文本控制台环境的服务器,它将是运行期间定位虚拟机性能问题的首选工具;

jstat命令使用格式:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
比如 jstat -gc -h3 31736 1000 10表示分析进程 id 为 31736 的 gc 情况,每隔 1000ms 打印一次记录,打印 10 次停止,每 3 行后打印指标头部。

jstat: 监视虚拟机各种运行状态信息

jstat(JVM Statistics Monitoring Tool) 使用于监视虚拟机各种运行状态信息的命令行工具。 它可以显示本地或者远程(需要远程主机提供 RMI 支持)虚拟机进程中的类信息、内存、垃圾收集、JIT 编译等运行数据,在没有 GUI,只提供了纯文本控制台环境的服务器上,它将是运行期间定位虚拟机性能问题的首选工具。

jstat 命令使用格式:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

比如 jstat -gc -h3 31736 1000 10表示分析进程 id 为 31736 的 gc 情况,每隔 1000ms 打印一次记录,打印 10 次停止,每 3 行后打印指标头部。

常见的 option 如下:

  • jstat -class vmid :显示 ClassLoader 的相关信息;
  • jstat -compiler vmid :显示 JIT 编译的相关信息;
  • jstat -gc vmid :显示与 GC 相关的堆信息;
  • jstat -gccapacity vmid :显示各个代的容量及使用情况;
  • jstat -gcnew vmid :显示新生代信息;
  • jstat -gcnewcapcacity vmid :显示新生代大小与使用情况;
  • jstat -gcold vmid :显示老年代和永久代的行为统计,从jdk1.8开始,该选项仅表示老年代,因为永久代被移除了;
  • jstat -gcoldcapacity vmid :显示老年代的大小;
  • jstat -gcpermcapacity vmid :显示永久代大小,从jdk1.8开始,该选项不存在了,因为永久代被移除了;
  • jstat -gcutil vmid :显示垃圾收集信息;

另外,加上 -t参数可以在输出信息上加一个 Timestamp 列,显示程序的运行时间。

jinfo:实时地查看和调整虚拟机参数

jinfo vmid :输出当前jvm进度的全部参数和系统属性(第一部分是系统的属性,第二部分是JVM的参数)。

jinfo -flag name vmid最大输出MaxHeapSize,查看当前jvm进程是否开启打印GC日志(-XX:PrintGCDetails:详细GC日志模式,这两个都是关闭的)。

C:\用户\ SnailClimb >金佛山  -旗MaxHeapSize 17340 
- XX:MaxHeapSize = 2124414976 
C:\用户\ SnailClimb >金佛山  -旗PrintGC 17340 
- XX:- PrintGC

使用jinfo可以在不重启虚拟机的情况下,可以动态的修改jvm的参数。尤其在线上的环境特别有用,请看下面的例子:

jinfo -flag [+|-]name vmid 开启或关闭对应名称的参数。

C:\用户\ SnailClimb >金佛山  -旗PrintGC 17340 
- XX:- PrintGC

C:\用户\ SnailClimb >金佛山  -+ PrintGC 17340

C:\用户\ SnailClimb >金佛山  -旗PrintGC 17340 
- XX:+ PrintGC

jmap:生成堆转储快照

jmap(Java的内存映射)命令用于生成堆转储快照。如果不使用jmap命令,要想获取Java堆转储,可以使用“-XX:+HeapDumpOnOutOfMemoryError”参数,可以让虚拟机在OOM异常出现之后自动生成转储文件,Linux命令下可以通过kill -3发送进程退出信号也能拿到dump文件。

jmap的作用并至少为了获取转储文件,它还可以查询finalizer执行变量,Java堆和永久代的详细信息,如空间使用率,当前使用的是收集器等。和jinfo一样,jmap有大量功能在Windows平台下也是受限制的。

示例,将通过jhat,Visual VM等工具分析该堆文件。

C:\ Users \ SnailClimb > jmap - dump:format = b 文件= C:\ Users \ SnailClimb \ Desktop \ heap.hprof 17340
将堆转储到C:\ Users \ SnailClimb \ Desktop \ heap.hprof ...
堆转储文件已创建

jhat:分析heapdump文件

jhat 用于分析heapdump文件,它会建立一个HTTP / HTML服务器,让用户可以在浏览器上查看分析结果。

C:\ Users \ SnailClimb > jhat C:\ Users \ SnailClimb \ Desktop \ heap.hprof
阅读C:\用户\ SnailClimb \桌面\ heap.hprof ...
创建周六日转储文件04  123031 CST 2019
快照读解决...
解决131419个对象...
追逐参考文献期望有26个点......................................
消除重复的引用...
快照已解决。
端口7000
服务器上已启动的HTTP服务器已准备就绪。

访问http:// localhost:7000 /

jstack :生成虚拟机当前时刻的线程快照

jstack(用于Java的堆栈跟踪)命令用于生成虚拟机当前时刻的线程快照。

生成线程快照的目的主要是定位线程连续出现停顿的原因,如线程间死锁,死循环,请求外部资源导致的连续等待等都是导致线程连续停顿的原因。线程出现停顿的时候通过jstack来查看各个线程的调用方式,就可以知道没有响应的线程到底在后台做些什么事情,或者在等待一些什么资源。

下面是一个线程死锁的代码。我们下面会通过jstack命令进行死锁检查,输出死锁信息,找到发生死锁的线程。

jstack查看死锁具体实例:https://blog.csdn.net/qq_29831979/article/details/82660767

JDK可视化分析工具

JConsole:Java监视与管理控制台

JConsole是基于JMX的可视化监视,管理工具。可以很方便地监视本地和远程服务器的java进程的内存使用情况。您可以在控制台输出console命令启动或者在JDK目录下的bin目录找到jconsole.exe然后双击启动。

连接Jconsole

连接Jconsole

如果需要使用JConsole连接远程进程,可以在远程Java程序启动时加上以下这些参数:

- Djava.rmi.server.hostname =外网访问的IP地址
- Dcom.sun.management.jmxremote.port = 60001 //监控的端口号
- Dcom.sun.management.jmxremote.authenticate = FALSE //关闭认证
- Dcom.sun.management.jmxremote.ssl = FALSE

在使用JConsole连接时,远程进程地址如下:

外网访问 ip 地址:60001 

查看Java程序概述

查看Java程序概述

内存监控

JConsole可以显示当前内存的详细信息。其他包括堆内存/非堆内存的整体信息,还可以细化到eden区,survivor区等的使用情况,如下图所示。

单击右边的“执行GC(G)”按钮可以强制应用程序执行一个Full GC。

  • 新生代GC(Minor GC):指代发生新生代的垃圾收集动作,Minor GC非常连续,回收速度一般也比较快。
  • 老年代GC(主要GC /完整GC):指发生在老年代的GC,出现了主要GC经常会伴随至少一次的次要GC(并非绝对),主要GC的速度一般会比次要GC的慢10倍以上。

内存监控

线程监控

类似我们jstack前面讲的命令,不过这个是可视化的。

最下面有一个“检测死锁(D)”按钮,点击这个按钮可以自动为您找到发生死锁的线程以及其的详细信息。

线程监控

可视VM:多合一故障处理工具

VisualVM提供在Java虚拟机(Java Virutal Machine,JVM)上运行的Java应用程序的详细信息。在VisualVM的图形用户界面中,您可以方便地,快捷地查看多个Java应用程序的相关信息。VisualVM官网:https: //visualvm.github.io/。VisualVM中文文档:https : //visualvm.github.io/documentation.html 。

下面这段话摘自《深入理解Java虚拟机》。

VisualVM(多合一Java故障排除工具)是立即随JDK发布的功能最强大的运行监视和故障处理程序,由官方在VisualVM的软件说明中写上了“多合一”的描述字样,预示着他除了运行监视,故障处理外,还提供了很多其他方面的功能,如性能分析(性能分析)。VisualVM的性能分析功能甚至比起JProfiler,YourKit等专业且收费的性能分析工具都不会逊色多少,而且VisualVM还有一个很大的优点:不需要被监视的程序基于特殊代理运行,因此他对应用程序的实际性能的影响很小,使他可以直接应用在生产环境中。这个优点是JProfiler,YourKit等工具无法与之媲美的。

VisualVM基于NetBeans平台开发,因此他一开始就有了插件扩展功能的特性,通过插件扩展支持,VisualVM可以做到:

  • 显示虚拟机进程以及进程的配置,环境信息(jps,jinfo)。
  • 监视应用程序的CPU,GC,堆,方法区以及线程的信息(jstat,jstack)。
  • dump以及分析堆转储快照(jmap,jhat)。
  • 方法级的程序运行性能分析,发现被调用最多,运行时间最长的方法。
  • 离线程序快照:收集程序的运行时配置,线程dump,内存dump等信息建立一个快照,可以将快照发送开发者处进行Bug反馈。
  • 其他插件的无限的可能性......

这里就不具体介绍VisualVM的使用,如果想了解的话可以看:



她喜欢所以就做咯