jstack分析程序卡顿(cpu占用)

情景

java程序在使用中出现卡顿,无响应,且刷新无效果

问题原因

可能是程序设计问题,出现死循环(小概率),设计缺陷,死锁

也可能是网络连接问题,需要具体分析

解决办法

使用jstack工具

jstack是JVM自带的Java堆栈跟踪工具,它用于打印出给定的java进程ID、core file、远程调试服务的Java堆栈信息.

这里因为不同的部署情况,有不同的方法来解决问题

docker容器

在出现卡顿时,不要停止docker容器,使用jstack来生成当前程序的快照,来判断当前进行的线程问题。

第一步

连接服务器 输入 top 来查看当前进程

按c 可以查看具体的启动信息和软件包位置

记下 前面的PID   ,按q退出top命令

第二步

输入 docker ps 查看容器内程序,找到需要检查的java容器id

第三步

输入 docker exec -it 容器id /bin/sh       进入到容器id 的/bin/sh中

第四步

jstack 进程id >输出文件名称

1.

到这里可以直接  cat 文件名称,直接查看,但是一般文件较长不易查询问题可以继续进行

2.

还有另一种解决办法,修改docker的启动配置,将主机文件挂载到容器上,这样生成的文件直接就会在主机对应目录中,不需要再拷贝

  • /path/on/host:/path/on/container
    `` 上述Compose文件将主机上的/path/on/host目录挂载到容器的/path/on/container`目录。

第五步(非必要)

exit 退出docker

docker cp 容器id(或名称):文件地址  主机目录   --将容器 的 目录(文件)拷贝到主机的目录中。

java程序

  • top
  • top -Hp pid 得到线程id
  • jstack pid
  • jstack -l [PID] >/tmp/log.txt
  • 分析堆栈信息

在 jstack.log 中查找对应的十六进制线程 ID,分析该线程的堆栈信息,定位高 CPU 占用的代码

分析文件

  • 执行jstack命令,将得到进程的堆栈信息。一般使用jstack -l pid来得到长列表,显示其详细信息。
  • 有时线程挂起的时候,需要执行jstack -F pid来获取。
  • 在实际运行中,往往一次 dump的信息,还不足以确认问题。建议产生三次 dump信息,如果每次 dump都指向同一个问题,我们才确定问题的典型性。
  • 堆栈信息只是一种参考,一些正常RUNNING的线程,由于复杂网络环境和IO的影响,也是有问题的,用jstack就无法定位,需要结合对业务代码的理解。

在dump 文件里,写法可能不太一样:

  • 死锁,Deadlock(重点关注)
  • 执行中,Runnable
  • 等待资源,Waiting on condition(重点关注)
  • 等待获取监视器,Waiting on monitor entry(重点关注)
  • 对象等待中,Object.wait() 或 TIMED_WAITING
  • 暂停,Suspended
  • 阻塞,Blocked(重点关注)
  • 停止,Parked

Blocked

线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。
如果线程处于Blocked状态,但是原因不清楚。可以使用jstack -m pid得到线程的mixed信息。

0xff31e8b8 ___lwp_cond_wait + 0x4

0xfea8c810 void ObjectMonitor::EnterI(Thread*) + 0x2b8

0xfeac86b8 void ObjectMonitor::enter2(Thread*) + 0x250

例如,以上信息表明,线程在尝试进入同步块时阻塞了。

### 定位 MySQL 服务器中 CPU 使用率高的 Java 进程 #### 使用 `top` 或 `htop` 查看进程 为了识别哪些进程占用了最多的 CPU 资源,可以使用命令行工具 `top` 或者更直观的 `htop` 来监控系统的实时性能状况。这些工具能够帮助确认是否存在名为 mysqld 的 MySQL 进程以及其它可能影响系统性能的应用程序,比如 Java 应用程序[^1]。 ```bash top ``` 或者安装并启动 htop: ```bash sudo apt-get install htop # 如果尚未安装的话 htop ``` 在上述界面中寻找 CPU 列表里消耗较高的条目,并注意它们对应的 PID (Process ID),这有助于进一步分析具体的线程行为[^4]。 #### 结合 `ps` 和 `grep` 找到特定于 Java 的高负载进程 当面对混合部署环境中的问题时——即在同一台机器上同时运行着 Java 工程和 MySQL 数据库的情形下,可以通过组合使用 `ps aux | grep java` 命令来筛选出所有正在执行的 Java 相关任务及其关联的信息,从而缩小范围至那些可能是造成瓶颈的原因所在[^5]。 ```bash ps aux | grep java ``` 此操作会返回一系列有关 JVM 实例的数据,包括但不限于用户名、PID、内存利用率等重要参数;对于每一个可疑对象,都可以继续深入探究其内部运作情况。 #### 获取详细的线程信息 一旦确定了一个或多个疑似引起 CPU 高负荷的 Java 进程,则可利用以下指令获取更加详尽的线程详情,特别是针对那个被怀疑的对象(假设已知其 PID 为 4380): ```bash jstack -l <pid> ``` 例如, ```bash jstack -l 4380 > thread_dump.txt ``` 这样做之后便可以获得一份完整的堆栈跟踪记录保存在一个文件当中,便于后续审查是否有任何异常活动或是死锁现象存在。 #### 综合考虑多方面因素进行优化调整 考虑到实际场景中提到的现象是在月末由于用户访问量增加而导致的服务响应变慢甚至卡顿的问题,在完成以上诊断流程的基础上还需要综合评估整个架构设计合理性,适当调优应用程序逻辑结构与数据库交互方式,确保即使面临高峰期也能维持稳定高效的运转状态[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值