Java 进程资源使用率较高问题定位

概述

在实际开发过程中,有些 Java 程序在本地或者在服务器上都可以运行的较正常,但是运行较长一段时间后,可能会出现资源占用率较高的情况,例如 CPU 或 内存占用率较高等情况,以至于发生内存溢出,进程假死等的情况。这些问题发生的原因,往往是那些易忽略的编程规范导致的。下面描述一个定位开发环境上资源占用率较高问题的流程。

  1. top 命令查看资源占用率进程
    获得占用资源较高的进程 pid 后,可以通过 ps -ef | grep pid 查看该进程属于哪一个服务,方便后续查看具体代码,搜索问题。
  2. 查看该进程下哪些线程资源占用率较高
    使用 top -Hp pid 可以查看该进程下各线程的资源占用情况,找到资源占用较高的线程 pid,此处以 t_pid 表示该值。此处需要切换为执行 pid 进程的用户来查看进程信息。
    后续使用的命令可能需要自己下载对应版本的 jdk,一般环境上只提供服务运行的 jre。这里简单的方式为下载服务对应的 java 版本的 jdk,例如放在 /tmp 目录下,配置 ~/.bashrc 文件,添加如下内容,并执行 source .bashrc。
JAVA_HOME=/tmp/jdk/
JRE_HOME=$JAVA_HOME/jre
JAVA_BIN=$JAVA_HOME/bin
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME PATH CLASSPATH
export JAVA_OPTS=-Djava.awt.headless=true
  1. 查看 pid 进程的堆栈信息
    使用 jstack pid 查看该进程下各线程的堆栈信息,搜索线程中 nid 值为上一步获得的 t_pid 线程。如果是一般用户线程,则可以根据线程的调用链,在服务代码中定位出具体故障位置。
  2. 查看内存使用情况
    使用 jmap -heap pid 查看内存中各区域使用情况,使用 jmap -histo pid 查看内存中的存储对象类型。如果上一步堆栈信息中占用资源较高的线程为 GC 线程的话,则该步骤查看的内存使用情况可以辅助判断 GC 的性能优略。
    如果是 CPU 使用率过高,一般是该 t_pid 为一个死循环;如果是内存使用率过高,则该 t_pid 可能为 GC 线程或构造对象线程。

下面提供一种曾经遇到过的场景供参考:
使用 top 命令查看资源使用情况时发现,CPU 使用率一直较高,内存使用率忽高忽低。在具体进程中发现有两个线程的 CPU 使用率较高,在进程堆栈中查看这两个线程一个为 VM Thread 协调线程,一个为 GC 线程。查看内存使用,发现偶尔内存各区域会出现占满情况,且存储大量 Map 的 Entry 对象,因为关联关系为强引用,导致 GC 效率较低且频繁执行,进程空间得不到释放,直到线程执行完毕。

参考

Java 进程资源使用率较高问题定位

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

融极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值