干货-深入理解Java虚拟机-2-虚拟机性能监控命令与故障处理工具

举报
老司机张师傅 发表于 2022/07/26 23:13:18 2022/07/26
【摘要】 前言基础不牢,地动山摇,菜如老哥还经常巩固自己的基本功,你就更要努力学习了。最近博主在复习Java虚拟机,对Java虚拟机的理解又有了一个更深层次的理解,记录下一些笔记及重点摘要,让我们一起学习一下吧! 现在用不上,不代表以后就能用上,一句话,学,就行了。 学习JVM有什么意义和作用?1、学习JVM能更深入的理解Java这门语言,能理解Java语言底层的执行过程。2、学习JVM,为了项目上...

前言

基础不牢,地动山摇,菜如老哥还经常巩固自己的基本功,你就更要努力学习了。
最近博主在复习Java虚拟机,对Java虚拟机的理解又有了一个更深层次的理解,记录下一些笔记及重点摘要,让我们一起学习一下吧!

现在用不上,不代表以后就能用上,一句话,学,就行了。

学习JVM有什么意义和作用?

1、学习JVM能更深入的理解Java这门语言,能理解Java语言底层的执行过程。
2、学习JVM,为了项目上线后去排查一些程序log日志中无法呈现的问题,可以通过GC日志来排查项目问题以及进行调优。
3、能够利用一些工具,jmap, jvisualvm, jstat, jconsole等工具可以辅助你观察Java应用在运行时堆的布局情况,由此你可以通过调整JVM相关参数提高Java应用的性能。
4、学习之前面试官虐待你你会觉得很痛苦,学完之后再被虐待时你会觉得很享受。

链接附上:《干货-深入理解Java虚拟机》
在这里插入图片描述

正文

1. 监控命令

jps:

可以列出正在进行的虚拟机进程, 并显示出虚拟机执行主类(main函数所在类)名称及这些进程的本地虚拟机唯一ID(LVMID),大多数监控命令都需要LMVID来确定监控的是哪个进程,所以jps命令也是使用最为频繁的指令,对于本地虚拟机来说,LVMID和进程id(PID)是一致的。
命令格式: jps [options] [hostid]
示例: jps -l
参数列表:

参数 说明
-q 值输出LVMID,省略主类名称
-m 输出虚拟机进程启动时传递给主类main()的参数
-l 输出主类的全名,如果进程执行的是jar包,输出jar包路径
-v 输出虚拟机进程启动时jvm参数

jstat:

用于监视虚拟机各种运行状态信息的命令行工具,可以显示本地或者远程虚拟机进程中的类加载、内存、拉锯班车、JIT编译等运行数据,在没有界面,只提供纯文本控制台环境的服务器上,他是运行期定位虚拟机性能问题的首选工具。
命令格式:jstat [ option vmid [interval[s|ms] [count]] ]
对于VMID和LVMID需要说明一下:如果是本地虚拟机,VMID和LVMID是一致的,如果是远程虚拟机,那么VMID的格式应该是:
[protocol:] [//] lvmid[@hostname[:port]/servername]
参数interval 和count代表查询间隔和统计次数,如果省略这两个参数,说明只查询一次,假设需要250毫秒查询一次进程2764的垃圾收集情况,一共查询20次。
示例: jstat -gc 2764 250 20
参数列表:

参数 说明
-class 值输出LVMID,省略主类名称
-gc 输出虚拟机进程启动时传递给主类main()的参数
-gccapacity 输出主类的全名,如果进程执行的是jar包,输出jar包路径
-gcutil 监视内容与-gc基本相同,但输出主要关注已使用的空间占总空间的百分比
-gccause 与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因
-gcnew 监视新生代GC的情况
-gcnewcapacity 监视内容与-gcnew基本相同,输出主要瑞士使用到的最大最小空间
-gcold 监视老年代GC情况
-gcoldcapacity 与-gcold基本相同,输出主要关注使用到的最大、最小空间
-gcpermcapacity 输出永久代使用的最大最小空间
-compiler 输出JIT编译器编译过的方法、耗时等信息
-printcompilation 输出已经被JIT编译的方法

jinfo:

实时查看和调整虚拟机的各项参数,使用jps -v 可以查看虚拟机启动时显示指定的参数列表,但如果想要知道未被显示的系统默认值除了查资料外,就只能使用jinfi的-flag选项进行查询(JDK1.6以上的版本使用java -XX:+PrintFlagsFinal也可以)。jinfo还可以使用-sysprops选项把进程中的System.getProperties()内容打印出来。在JDK1.6之后,可以通过-flag[+|-] name 或者-flag name=value的形式来修改一部分运行期可写的参数值
命令格式: jnifo [option] pid
示例: 查询CMSInitiatingOccupancyFraction参数值
jinfo -flag CMSInitiatingOccupancyFraction 1444
结果

 -XX:CMSInitiatingOccupancyFraction =85

jmap:

用于生成堆转储快照(一般称为heapdump或者dump文件),当然也有其他的一些手段可以获取dump文件,例如通过kill -3命令发送进程退出信号(不会影响程序的运行),也能拿到dump文件,还有一些其他的方法可以自行百度。
jmap的作用不仅仅是为了获取dump文件,它还可以查询finalize执行队列、Java堆和永久代的详细信息如空间使用率、当前用的是哪种收集器等信息。
命令格式: jmap [option] vmid
示例: jmap -dump:format=b,file=eclipse.bin 3500
结果

Dumping heap to C:\Users\IcyFenix\eclipse.bin ...
    Heap dump file crested

参数列表:

参数 说明
-dump 生成Java堆转储快照,格式为:-dump:[live, ]format=b,file=<filename>,其中live子参数说明是否只dump出存活的对象
-finalizerinfo 显示在F-Queue中等待Finalizer线程执行finalze方法的对象,只在Linux/Solaris平台下有效。
-heap 显示Java堆详细信息。如使用哪种回收器、参数配置、分代状况等。只在Linux/Solaris平台下有效。
-histo 显示堆中对象统计信息,包括类、实例数量、合计容量。
-permstat 以ClassLoader为统计口径显示永久代内存状态。只在Linux/Solaris平台下有效。
-F 当虚拟机进程堆-dump没有响应时,可使用这个选项强制生成dump快照。只在Linux/Solaris平台下有效。

jhat:

jhat来分析jmap生成的堆转储快照。jhat内置了一个微型的http/html服务器,生成dump文件的分析结果后,可以通过浏览器进行查看。
命令格式: jhat [dump文件]
示例: jhat eclipse.bin
结果:

Reading from eclipse.bin...
Server is ready.

出现Server is ready提示后,在浏览器输入http://ip:7000/就可以看到分析结果了。
分析结果默认以包为单位进行分组显示,分析内存泄漏问题主要会使用到其中的“Heap Histogram”与OQL页签的功能,前者可以找到内存中容量最大的对象,后者是标准的对象查询语言,使用类似于SQL的语法对内存中的对象进行查询统计,如果对OQL有兴趣可以自行百度。

jstack:

用于生成虚拟机当前时刻的线程快照(一般成为threaddump或者javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致长时间等待等都是常见原因。
线程出现停顿的时候,通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么,或者等待什么资源。
命令格式: jstack [option] vmid
示例: jstack -l 3500

<%@ page import="java.util.Map" %><%--
  Created by IntelliJ IDEA.
  User: zhanghang
  Date: 2021/6/1
  Time: 9:34
  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 = stackTrace.getKey();
                StackTraceElement[] stacks = stackTrace.getValue();
                if (thread.equals(Thread.currentThread())){
                    continue; // 当前线程不需要展示
                }
                System.out.println("线程:"+thread.getName());
                for (StackTraceElement stack : stacks) {
                    System.out.println("\t"+stack);
                }
            }
        %>
    </pre>
</body>
</html>

2. 可视化监控工具

VisualVM:

一款可视化多合一故障处理工具,专门监控Java的虚拟机进程,其功能十分强大,相关包Oracle已经在github上面开源,网上有很多相关资源,有兴趣学习的小伙伴可以自行百度搜索(搜索近一年的)。

以上就是博主本次关于虚拟机的学习分享,谢谢大家观看,记得一键三连哦!

另外,附上学习书籍:《深入理解Java虚拟机》,需要某宝可以进行购买
在这里插入图片描述

你只有通过自身不懈的努力,才能受到社会不断的毒打,干就完了!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。