百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

java问题诊断和问题排查工具

mhr18 2025-02-15 16:33 17 浏览 0 评论

在JDK的bin目录下有很多命令行工具,命令行工具的好处是:当应用程序部署到生产环境后,无论是直接接触物理服务器还是远程telnet到服务器上都会受到限制。而借助tools.jar类库里面的接口,我们可以直接在应用程序中实现功能强大的监控分析功能。

  1. jps:查看本机java进程信息
  2. jstack:打印线程的信息,制作 线程dump文件
  3. jmap:打印内存映射信息,制作 堆dump文件
  4. jstat:性能监控工具
  5. jhat:内存分析工具,用于解析堆dump文件并以适合人阅读的方式展示出来
  6. jconsole:简易的JVM可视化工具
  7. jvisualvm:功能更强大的JVM可视化工具
  8. javap:查看字节码

JAVA Dump:就是虚拟机运行时的快照,将虚拟机运行时的状态和信息保存到文件中,包括:

  1. 线程dump:包含所有线程的运行状态,纯文本格式
  2. 堆dump:包含所有堆对象的状态,二进制格式

jps

显示当前所有java进程pid的命令,我们可以通过这个命令来查看到底启动了几个java进程(因为每一个java程序都会独占一个java虚拟机实例),不过jps有个缺点是只能显示当前用户的进程id,要显示其他用户的还只能用linux的ps命令。

jps -l 输出应用程序main.class的完整package名或者应用程序jar文件完整路径名

jps -v 输出传递给JVM的参数

jps失效

我们在定位问题过程会遇到这样一种情况,用jps查看不到进程id,用ps -ef | grep java却能看到启动的java进程。要解释这种现象,先来了解下jps的实现机制:java程序启动后,会在目录/tmp/hsperfdata_{userName}/下生成几个文件,文件名就是java进程的pid,因此jps列出进程id就是把这个目录下的文件名列一下而已,至于系统参数,则是读取文件中的内容。

我们来思考下:如果由于磁盘满了,无法创建这些文件,或者用户对这些文件没有读的权限。又或者因为某种原因这些文件或者目录被清除,出现以上这些情况,就会导致jps命令失效。

如果jps命令失效,而我们又要获取pid,还可以使用以下两种方法:

1、top | grep java
2、ps -ef |grep java

jstack

主要用于生成指定进程当前时刻的线程快照,线程快照是当前java虚拟机每一条线程正在执行的方法堆栈的集合。比如我们定位线上cupu飙高,

  1. 先用top找出占据cpu的java进程的pid,
  2. 然后再使用jstack ${pid} > a.txt,此时txt保存的都说16进制的
  3. 然后使用top -Hp ${pid},会展现但是此时线程是十进制,找出那个占据cpu最高的线程,需要转换成16进制,可以使用 printf "%x" ${threadId} 我这里是430224, 得到十六进制的69090
  1. 使用vi命令进入命令模式,输入:/69090 查看对应的堆栈或者sz a.txt下载到本地桌面,用记事本打开a.txt找到对应线程id 69090

jmap

主要用于打印指定java进程的共享对象内存映射或堆内存细节。堆Dump是反映堆使用情况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。一般在内存不足,GC异常等情况下,我们会去怀疑内存泄漏,这个时候就会去打印堆Dump。

  1. jmap -heap pid:查看堆使用情况
  1. jmap -histo pid:查看堆中对象数量和大小

打印的信息分别是:序列号、对象的数量、这些对象的内存占用大小、这些对象所属的类的全限定名。如果是内部类,类名的开头会加上*,如果加上live子参数的话,如jmap -histo:live pid,这个命名会触发一次FUll GC,只统计存活对象

  1. jmap -dump:format=b,file=heapdump pid:将内存使用的详细情况输出到文件

然后使用jhat命令查看该文件:jhat -port 4000 文件名 ,在浏览器中访问http:localhost:4000/ 不过还是建议使用jdk自带的jvisuavm该命令适用的场景是程序内存不足或者GC频繁,这时候很可能是内存泄漏。通过用以上命令查看堆使用情况、大量对象被持续引用等情况。但是执行此命令会导致程序触发stop the word短暂暂停

jstat

主要是对java应用程序的资源和性能进行实时的命令行监控,包括了对heap size和垃圾回收状况的监控。jstat -

  • option:我们经常使用的选项有gc、gcutil
  • vmid:java进程id
  • interval:间隔时间,单位为毫秒
  • count:打印次数

1、jstat -gc PID 5000 20

  • S0C:年轻代第一个survivor的容量(字节)
  • S1C:年轻代第二个survivor的容量(字节)
  • S0U:年轻代第一个survivor已使用的容量(字节)
  • S1U:年轻代第二个survivor已使用的容量(字节)
  • EC:年轻代中Eden的空间(字节)
  • EU:年代代中Eden已使用的空间(字节)
  • OC:老年代的容量(字节)
  • OU:老年代中已使用的空间(字节)
  • PC:永久代的容量
  • PU:永久代已使用的容量
  • YGC:从应用程序启动到采样时年轻代中GC的次数
  • YGCT:从应用程序启动到采样时年轻代中GC所使用的时间(单位:S)
  • FGC:从应用程序启动到采样时老年代中GC(FULL GC)的次数
  • FGCT:从应用程序启动到采样时老年代中GC所使用的时间(单位:S)

2、jstat -gcutil PID 5000 20

  • s0:年轻代中第一个survivor已使用的占当前容量百分比
  • s1:年轻代中第二个survivor已使用的占当前容量百分比
  • E:年轻代中Eden已使用的占当前容量百分比
  • O:老年代中已使用的占当前容量百分比
  • P:永久代中已使用的占当前容量百分比

5、jhat(基本不会用)

主要用来解析java堆dump并启动一个web服务器,然后就可以在浏览器中查看堆的dump文件了。生成dump文件的方法前面已经介绍了,这边主要介绍如何解析java堆转储文件,并启动一个web server

jhat heapdump

这个命令将heapdump文件转换成html格式,并且启动一个http服务,默认端口为7000。如果端口冲突,可以使用以下命令指定端口:jhat -port 4000 heapdump 下面我们来访问下:ip:port

可视化监控工具JVisualVM

其实还有个JConsole工具,但是jvisualVM功能比它更多更强大,所以主要了解它即可

VisualVM(All-in-One Java Troubleshooting Tool)是 Oracle 提供的功能最强大的运行监视和故障处理程序之一, 它除了支持常规的运行监视、故障处理等功能外,还能用于性能分析(Profiling)。同时因为 VisualVM 是基于 NetBeans 平台的开发工具,所以它还支持通过插件来进行功能的拓展。VisualVM 的主要功能如下:

  • 显示虚拟机进程及其配置信息、环境信息(与 jps、jinfo 功能类似);
  • 监视应用程序的处理器、垃圾收集、堆、方法区以及线程的信息(与 jstat、jstack 功能类似);
  • dump以及分析堆转储快照(与 jmap、jhat 功能类似);
  • 方法级的程序运行性能分析,找出被调用最多、运行时间最长的方法;
  • 离线程序快照:可以收集程序的运行时配置、线程 dump、内存 dump 等信息来建立快照

#使用

打开位于 bin 目录下的 jvisualvm 程序, 它会自动扫描当前主机上的所有 JVM 进程:

点击需要监控的进程后,右侧即会显示相关的监控信息:

1. 堆 Dump

在监控界面点击按钮可以 执行垃圾回收 或者 堆 Dump 。进行堆 Dump 后,还会显示其分析结果:

2. 线程 Dump

在线程界面可以查看所有线程的状态,如果出现死锁,该界面还会进行提示:

此时可以进行 线程 Dump 来获取具体的线程信息,效果和 jstack 命令类似:

3. 性能分析

在 Profiler 界面,可以进行 CPU 和 内存的性能分析。要开始性能分析,需要先选择 CPU内存 按钮中的一个,VisualVM 将会开始记录应用程序执行过的所有方法:如果是进行的是 CPU 执行时间分析,将会统计每个方法的执行次数、执行耗时;如果是内存分析,则会统计每个方法关联的对象数以及这些对象所占的空间。想要结束性能分析,点击停止按钮即可:

4. Visual GC

Visual GC 面板默认是不显示的,需要通过插件进行扩展。它会实时监控虚拟机的状态,在功能上类似于 jstat 命令:

安装插件

在主界面,点击 工具 => 插件 ,可以打开插件面板。右击插件选项或者点击安装按钮即可完成对应插件的安装:

连接远程进程

以上演示 JConsole 和 VisualVM 时,我们都是用的本地进程,但在实际开发中,我们更多需要监控的是服务器上的远程进程。想要监控远程主机上的进程,需要进行 JMX 的相关配置,根据连接时是否需要用户名和密码,可以分为以下两种配置方式:

#不使用安全凭证

启动服务器上的 Java 进程时增加以下参数:或者把它配到jvm参数配置中

 java -Dcom.sun.management.jmxremote.port=12345  #jmx远程连接的端口号
 -Dcom.sun.management.jmxremote.ssl=false 
 -Dcom.sun.management.jmxremote.authenticate=false  
 -jar springboot.jar 

此时只需要知道主机地址和端口号就可以连接,不需要使用用户名和密码,所以安全性比较低。

使用安全凭证

启动服务器上的 Java 进程时增加以下参数:

java -Dcom.sun.management.jmxremote.port=12345 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=true 
-Dcom.sun.management.jmxremote.access.file=/usr/local/jmxremote.access 
-Dcom.sun.management.jmxremote.password.file=/usr/local/jmxremote.password 
-jar springboot.jar 

其中 jmxremote.access 的内容如下,其中 admin 为用户名,readwrite 表示可读可写,也可以设置为 readonly(只读):

admin readwrite  

jmxremote.password 的内容如下,其中 admin 为用户名,123456 为密码:

admin 123456

两个文件创建好后,还需要赋予其执行权限:

chmod 600 /usr/local/jmxremote.access
chmod 600 /usr/local/jmxremote.password
chown root:root /usr/local/jmxremote.access
chown root:root /usr/local/jmxremote.password

之后在使用 VisualVM 进行远程连接时,配置如下:

需要注意的是这里的端口号是配置的
Dcom.sun.management.jmxremote.port 的值,而不是 Java 程序的端口号。连接完成后,即可查看到对应进程的监控状态


参考文档:Java问题诊断和排查工具(查看JVM参数、内存使用情况及分析) | 二哥的Java进阶之路

相关推荐

甲骨文签署多项大型云协议,其一未来可贡献超300亿美元年收入

IT之家7月1日消息,根据甲骨文Oracle当地时间6月30日向美国证券交易委员会(SEC)递交的FORM8-K文件,该企业在始于2025年6月1日的202...

甲骨文获TEMU巨额合同,后者大部分基础设施将迁移至Oracle云

IT之家6月23日消息,Oracle甲骨文创始人、董事长兼首席技术官LarryEllison(拉里埃里森)在本月早些时候的2025财年第四财季和全财年财报电话会议上表示,Oracle...

Spring Boot 自定义数据源设置,这些坑你踩过吗?

你在使用SpringBoot进行后端开发的过程中,是不是也遇到过这样的问题:项目上线后,数据库连接总是不稳定,偶尔还会出现数据读取缓慢的情况,严重影响了用户体验。经过排查,发现很大一部分原因竟然...

一个开箱即用的代码生成器(一个开箱即用的代码生成器是什么)

今天给大家推荐一个好用的代码生成器,名为renren-generator,该项目附带前端页面,可以很方便的选择我们所需要生成代码的表。首先我们通过git工具克隆下来代码(地址见文末),导入idea。...

低代码建模平台-数据挖掘平台(低代码平台的实现方式)

现在来看一下数据连接。·这里是管理数据连接的空间,点击这里可以新增一个数据连接。·输入连接名称,然后输入url,是通过gdbc的方式去连接的数据库,目前是支持mysql、oracle以及国产数据库达梦...

navicat 17.2.7连接oracle数据库提示加载oracle库失败

系统:macOS15.5navicat版本:navicatpremiumlite17.2.7连接oracle测试报错:加载oracle库失败【解决办法】:放达里面找到程序,显示简介里面勾选“使...

开源“Windows”ReactOS更新:支持全屏应用

IT之家6月17日消息,ReactOS团队昨日(6月16日)在X平台发布系列推文,公布了该系统的最新进展,包括升级Explorer组件,支持全屏应用,从Wine项目引入了...

SSL 推出采用全模拟内置混音技术的模拟调音台Oracle

英国调音台传奇品牌SolidStateLogic宣布推出Oracle——一款采用全模拟内置混音技术的调音台,在紧凑的AWS尺寸机箱内集成了大型调音台的功能。该调音台提供24输入和...

47道网络工程师常见面试题,看看有没有你不会的!

你们好,我的网工朋友。网络工程师面试的时候,都会被问到什么?这个问题其实很泛,一般来说,你肯定要先看明白岗位需求写的是什么。基本上都是围绕公司需要的业务去问的。但不可否认的是,那些最基础的概念,多少也...

汉得信息:发布EBS系统安装启用JWS的高效解决方案

e公司讯,从汉得信息获悉,近日,微软官方宣布InternetExplorer桌面应用程序将于2022年6月15日正式停用。目前大部分客户都是使用IE浏览器打开EBS的Form界面,IE停用后,只能使...

36.9K star ! 推荐一个酷炫低代码开发平台!功能太强!

前言最近在逛github,看看能不能搜罗到一些对自己有帮助的开源软件。不经意间看到一个高star的java开源项目:jeecg-boot。进入在线演示版一看,感叹实在是太牛了!此开源项目不管是给来学习...

Linux新手入门系列:Linux下jdk安装配置

本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...

手把手教你在嵌入式设备中使用SQLite3

摘要:数据库是用来存储和管理数据的专用软件,使得管理数据更加安全,方便和高效。数据库对数据的管理的基本单位是表(table),在嵌入式linux中有时候它也需要用到数据库,听起来好难,其实就是几个函数...

JAVA语言基础(java语言基础知识)

一、计算机的基本概念什么是计算机?计算机(Computer)全称:电子计算机,俗称电脑。是一种能够按照程序运行、自动高速处理海量数据的现代化智能电子设备。由硬件和软件组成、没有安装过任何软件的计算机称...

再见 Navicat!一款开源的 Web 数据库管理工具!

大家好,我是Java陈序员。在日常的开发工作中,常常需要与各种数据库打交道。而为了提高工作效率,常常会使用一些可视化工具进行操作数据库。今天,给大家介绍一款开源的数据库管理工具,无需下载安装软件,基...

取消回复欢迎 发表评论: