windows下监控和分析java进程

最近查问题时发现有服务运行中内存占用超过90%造成页面卡顿,在网上查了无数资料后,开始我的找bug路程了:

1、利用任务管理器或者jps命令找到我的程序的进程ID

这里写图片描述

在cmd控制台下输入jps命令,即可列出当前电脑运行的java程序的所有进程,我的程序的进程ID为26028

2、利用jstack命令列出进程的所有信息

这里写图片描述

使用命令jstack 26028 > 26028.txt列出进程ID为26028的进程信息,并输出到26028.txt文本文件中。 
之后打开这个文件可以看到当前进程的所有线程信息,包括线程的状态、线程的ID号以及堆栈信息等。 
在文件的最后,我们会看到几个负责GC的线程,nid就是线程的ID:

这里写图片描述

3、使用pslist工具查看进程的所有线程的详细信息

在cmd控制台输入pslist,如果命令不被识别,则表示当前电脑上没有安装pslist这个工具,可以到windows官方网站: 
https://technet.microsoft.com/en-us/sysinternals/bb896682.aspx下载,下载完成后将其解压到C:\Windows\System32路径下即可使用,或者将其配置到环境变量中亦可。

安装完成后,使用pslist -dmx 26028 > 26028_pslist.txt命令,可以列出进程ID为26028的进程下的所有线程的详细信息(线程ID、上下文切换,状态等)。

这里写图片描述

打开输出的文件,可以看到:

这里写图片描述

从这个文件所列的信息中,我们可以找到最耗资源的线程。然后将其Tid(线程ID)转换成十六进制(直接利用windows下的计算器即可),到使用jstack命令产生的文件中查找,可以查到具体哪一个线程在干什么,为什么这么耗资源?


最后,我发现我的程序最耗资源的线程是所有GC线程,而程序中我的工作线程基本上都处于阻塞状态(以上截图并没有体现,进程26028是正常运行时我截的图)。那么为什么GC这么耗资源呢?一开始我认为是哪一个资源忘记释放了,于是我将打开的字节流、socket资源等都确认关闭了一遍。可是重新运行程序4、5个小时之后依然出现了同样的问题。显然问题并没有解决。


4、jmap+MAT分析

MAT工具的安装以及使用,网上有很多资料,这里就不做赘述了。

运行程序,当问题出现时,使用jmap指令将内存dump到文件,命令是:jmap -dump:format=b,file=jmap.bin 26028.

然后使用MAT工具加载该dump文件即jmap.bin,进行分析。

最后发现有一种数据库连接对象在内存中积累,占据了将近3G的内存,奇怪的是这段代码我在很多程序中复用过,都没有出现过问题。所以我判断应该是由于高并发造成的问题,数据库可能承受不了这么大的压力。

我将存入数据库的代码先注释掉,改成存储到文件之后,就一切正常了。

好了,bug是找到了,接下来我该去看看高并发的数据库设计了。


接下来我再介绍调bug过程中用到的几款工具。

5、jconsole和jvisualvm工具

这两个工具都是JDK自带的监控java程序的工具,可以监控本地进程和远程进程。jvisualvm提供的信息更多一点。 
直接在cmd控制台输入jconsolejvisualvm就可以调出这两个工具。 
jconsole的界面如下:

这里写图片描述

jvisualvm的界面如下:

这里写图片描述

6、windows提供的process explorer工具

该工具可以到网上下载,它提供比任务管理器更详细的进程信息,并且可以查看每个进程下的线程:

这里写图片描述

这里写图片描述


您可以在 Windows 操作系统编写一个批处理脚本(.bat 文件),然后使用 Windows 自带的任务计划程序来定时启动该脚本,实现对 Java 进程监控和拉起。具体步骤如下: 1. 编写批处理脚本 在记事本等文本编辑器新建一个文件,将以下代码复制进去: ``` @echo off setlocal if not "%1"=="" ( set JAVA_HOME=%1 ) else ( set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_191 ) set CLASSPATH=.;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar; set PATH=%JAVA_HOME%\bin;%PATH% set MAIN_CLASS=com.example.Main set ARGS= :loop for /f "tokens=1,2" %%a in ('jps -m ^| findstr %MAIN_CLASS%') do ( set PID=%%a set CMD=%%b goto found ) :start echo [%time%] %MAIN_CLASS% is not running, starting... start java %MAIN_CLASS% %ARGS% goto loop :found echo [%time%] %MAIN_CLASS% is running with PID %PID% echo [%time%] %CMD% timeout /t 10 > nul goto loop ``` 其,`set JAVA_HOME` 指定 Java 的安装路径,`set MAIN_CLASS` 指定要监控Java 主类,`set ARGS` 可以指定 Java 程序的运行参数。 2. 设置任务计划程序 按下 Windows+R 键打开运行对话框,输入 `taskschd.msc` 打开任务计划程序。在左侧的面板,选择“任务计划程序库”,然后在右侧的面板,点击“创建任务”。 在“常规”选项卡,输入任务名称和描述,选择“使用最高权限运行”,并勾选“不与用户会话相关”。 在“触发器”选项卡,点击“新建”,设置计划的触发方式,例如定时启动、开机启动等。 在“操作”选项卡,点击“新建”,选择要执行的程序为批处理脚本文件(.bat),并设置起始路径为批处理文件所在的目录。 在“条件”选项卡,可以设置任务的执行条件,例如只有在电源适配器插入时才执行任务等。 3. 启动任务 完成所有设置后,点击“确定”保存任务。然后在任务计划程序找到该任务,右键点击“运行”即可手动启动程序。如果一切正常,任务计划程序会按照设置的时间自动启动批处理脚本,对 Java 进程进行监控和拉起。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值