【Java】使用jstack、jstat、jmap线上问题排查一例

2024-01-15 10:18

本文主要是介绍【Java】使用jstack、jstat、jmap线上问题排查一例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

现象

前阵子线上发布了一些功能,主要是针对客户群做的社群网络,大数据这边针对用户的通讯录、通话记录、设备等信息,计算其对应的社群网络,然后根据社群对应的指标来判断用户的风险情况。当然新老用户的逻辑有所区分,这里就不再深入阐述了。功能上线后,出现了一个比较诡异的事情:系统CPU和内存都飙升,几乎都快把主机撑爆了。

定位最消耗资源的线程

因为发布是在凌晨,使用app的用户还是比较少的,经过沟通,我们建议运维暂时先不下线新功能。给我们几分钟时间定位问题。这时候我们首先想到要查看是哪个线程最消耗资源。(以下示例为事后线下复现,非当时线上真实资源消耗情况)

  • 查看java进程

ps -ef | grep kafka-1.0 | grep -v grep

93ec254723f7b96fb6e182b1faed8e88.png

  • 查看进程中最消耗资源的线程

在我们查看到进程号以后,可以通过top命令查看对应进程中的线程,以及cpu使用情况

top -Hp 100728

a80fd509765fa38b2e2d81aee627165f.jpeg

  • 转换为十六进制

printf "%x\n" 130870

12f87e7c20bb9e03c2931c1873d16a4b.png

可见线程号为:1ff36

接下来我们就需要用到jstack来查看

jstack 100728 > 100728.jstack

这样我们就把线上应用的堆栈信息给dump下来了,接下来我们可以看看jstack导出的文件主要有哪些内容,以及线程号为:1ff36的线程当时正在进行什么操作。截止目前我们使用的上面的示例实际并不是当时线上的截图,而是后续为了说明当时的场景做的。当时jstack导出的文件我们保留下来了,对应的最占用CPU资源的前几个线程为GC线程。我们有理由认为是内存被撑爆导致的频繁GC,进而导致CPU居高不下。 查看GC情况

/usr/local/jdk1.8.0_11/bin/jstat -gcutil 100728 1000 100

我们发现FGC特别频繁,几秒钟就会进行一次,因为full gc会导致stop the world所以这必然是有问题的,而S0,S1几乎为0,eden区和old区都占满了,即使进行了FGC依然无法回收,由此我们怀疑是在程序运行中产生了大对象无法回收导致频繁FGC: 

df72de034fd9875ac2c7f8a02f8f1475.png

使用IBM的dump文件分析工具

我们先看下jstack下来的文件内容:

c1e380acbe230686f06bfc9967870534.jpeg

推荐大家一个工具:IBM Thread and Monitor Dump Analyzer for Java(点击下载),真的是线程dump文件的分析利器,看起来非常直观。

使用该工具打开dump文件

934b7537240517c8003cf9576b07c704.jpeg

我们发现其中有大量的Waiting on condition等待,它们都是调用的sun.misc.Unsafe.park(Native Method)方法,再看看Thread Details都是hbase连接在获取数据

641699fed700c753357035c81aff2959.jpeg

这里很可能是因为获取了大量的数据导致的内存占用居高不下。但是目前也只能提供一个方向性的参考,并没有定位到具体的开发代码,我们看了这么多wait和调用的方法大多也都是定位到了开发框架的源码。我们可以通过搜索对应项目中的包,看看截止当时应用程序都执行了那些代码,如我们项目中所有的代码都是com.maiya开头的,很幸运目前用户流量还不大,并且调用的程序代码并不复杂,我们发现了一个可疑的地方:

1db57c39afb182f5054ca0aef8979545.jpeg

如上图所示,正是本次上线的代码,正在调用hbase的查询接口,那么是否就是hbase表的问题呢,难道如我们上面所猜想的,因为数据量过大导致的出现了大对象?我们count了下对应的表,发现表数据达到了惊人的2亿数据。而且一个用户下有多条重复数据,HBase中为什么会有重复数据呢?原来是因为key设计的问题,导致本该覆盖的记录,并没有覆盖,而是新增了。在数据重复统计多次以后,数据量猛增。最终导致了上面的问题。

至此已经定位出来原因了,程序并不需要进行修改,只要对HBase表进行重构,数据入库逻辑修改即可。数据修正后,程序重启后也正常了。 实际上我们也可以通过jmap查看程序中的class对象占用内存情况。不过dump出来的文件一般都比较大,大家要慎重。

使用java自带的jvisualvm,可以分析heap.hprof文件中的内容:

ec541b9ac49719f7f8a8364bbf8e8184.jpeg

使用jstack只能复现当时线程的方法栈,是一个静态的场景,所以一般要多导出几次,分析对比,如果某个应用程序线程在多次的jstack文件中一直存在,那么可能就需要我们多加关注了。

这篇关于【Java】使用jstack、jstat、jmap线上问题排查一例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/608554

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置