Java线上问题排查过程

 更新时间:2026年03月06日 14:14:54   作者:西红柿系番茄  
本文详细介绍了如何通过命令行和可视化工具来诊断和解决CPU和内存使用率过高的问题,包括找到高占用率的进程和线程,分析堆内存使用情况,以及在内存溢出时自动保存堆快照文件的方法

一、CPU使用率高

模拟代码

public class OnLine {

    public static void main(String[] args) {
        while (true) {
            // run
        }
    }
}

1)找到进程ID

方法一:top命令列出进程信息,按P(shift+p)让CPU占用率由高到低排序(按M是内存),由此看到最高的是java进程,PID为31416。

方法二:jps命令,看到启动类OnLine对应的PID为31416。

方法三:ps -ef | grep java,自己玩哈。

2)找到CPU占用率最高的线程(轻量级进程)ID

top -Hp PID命令列出指定进程里线程信息,同样按P排序,看到最高的线程ID为31420。

3)查看线程的堆栈信息

首先将十进制31420转为十六进制,使用命令printf '%x\n' xxx。然后用jstack命令配合grep命令输出线程的堆栈信息。

jstack 进程ID | grep '0x线程ID' -A 10

由此可以看到线程的状态和执行代码位置。

二、内存占用高

模拟代码

public class OnLine {

    private static final List<Byte[]> bytesList = new ArrayList<>();

    public static void main(String[] args) {
        for (int i = 0; i <= 10; i++) {
            Byte[] bytes = new Byte[1024 * 1024];
            bytesList.add(bytes);
        }
        LockSupport.parkNanos(TimeUnit.HOURS.toNanos(1));
    }
}

top命令列出进程信息,按M(shift+m)让内存占用率由高到低排序(按P是CPU),由此看到最高的是java进程,PID为13915。

1)将堆内存信息dump下来(生产环境需要谨慎)

jmap -dump:live,format=b,file=heap.bin 13915

jmap [options] pid

-dump:dump_options pid

Connects to a running process and dumps the Java heap. The dump_options include:

live --- When specified, dumps only the live objects; if not specified, then dumps all objects in the heap.

format=b --- Dumps the Java heap in hprof binary format

file=filename --- Dumps the heap to filename

Example: jmap -dump:live,format=b,file=heap.bin pid

2)分析堆快照信息

打开可视化工具jvisualvm(目录:JAVA_HOME/bin/),文件->装入,选择刚才dump的文件

打开之后,选择“类”,按“大小”降序,就可以看到各类的实例数量和内存占用大小的信息了

双击类所在行(比如上面的java.lang.Byte[]),选择实例,可以看到详细引用信息了

三、内存溢出

让JVM在发生内存溢出时自动dump堆快照文件

参数设置:

  • -XX:+HeapDumpOnOutOfMemoryError:内存溢出时,保存堆快照文件
  • -XX:HeapDumpPath=/home/zhh/:堆快照文件保存路径

还是采用上面的代码,启动参数设置如下

-Xms10M
-Xmx10M
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/home/zhh/

发生OOM时,在指定位置dump了堆快照文件,这时就可以拿去分析了(参考2)。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot实现消息推送的实战(让服务器学会"主动搭讪")

    SpringBoot实现消息推送的实战(让服务器学会"主动搭讪")

    本文介绍了如何使用SSE技术实现SpringBoot应用的消息推送,并提供了详细的实战步骤和优化建议,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2026-03-03
  • Java并发 synchronized锁住的内容解析

    Java并发 synchronized锁住的内容解析

    这篇文章主要介绍了Java并发 synchronized锁住的内容解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Java入门案列之猜拳小游戏

    Java入门案列之猜拳小游戏

    这篇文章主要为大家详细介绍了Java入门案列之猜拳小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • Mybatis-Plus insertBatch执行缓慢的原因查询

    Mybatis-Plus insertBatch执行缓慢的原因查询

    这篇文章主要介绍了Mybatis-Plus insertBatch执行缓慢的原因查询,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java垃圾回收之分代收集算法详解

    Java垃圾回收之分代收集算法详解

    今天小编就为大家分享一篇关于Java垃圾回收之分代收集算法详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • Spring boot JPA实现分页和枚举转换代码示例

    Spring boot JPA实现分页和枚举转换代码示例

    这篇文章主要介绍了Spring boot JPA实现分页和枚举转换代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Springboot内嵌SQLite配置使用详解

    Springboot内嵌SQLite配置使用详解

    这篇文章主要介绍了Springboot内嵌SQLite配置使用详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • Spring Cloud中使用Eureka的详细过程

    Spring Cloud中使用Eureka的详细过程

    Eureka 是 Netflix 开源的一个服务发现组件,它在微服务架构中扮演着重要的角色,这篇文章主要介绍了Spring Cloud中如何使用Eureka,需要的朋友可以参考下
    2024-07-07
  • Java HashMap源码及并发环境常见问题解决

    Java HashMap源码及并发环境常见问题解决

    这篇文章主要介绍了Java HashMap源码及并发环境常见问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Java Mybatis框架由浅入深全解析上篇

    Java Mybatis框架由浅入深全解析上篇

    MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码本文将为大家初步的介绍一下MyBatis的使用
    2022-07-07

最新评论