JAVA线上问题排查降龙十八掌

news2024/9/22 21:19:36

现场问题一般有以下几种问题 CPU,磁盘,内存,GC问题,网络

同时例如jstack、jmap等工具也是不囿于一个方面的问题的,基本上出问题就是df、free、top 三连,然后依次jstack、jmap伺候,具体问题具体分析即可。

CPU

1.top 查看 占用cpu多的线程

图片

 

2.然后通过 top -H -p pid 来找到使用率比较高得线程

比如66  top -H -p 66

3.使用printf '%x\n' pid 得到nid

4.然后使用 jstack pid | grep 'nid' -C10 来查看堆栈信息

频繁gc

使用 jstat -gc pid 1000   其中1000代表采样间隔(ms)

 字段含义

s0c s1c   表示survivor 0 1 区域的容量 
s0u s1u   表示survivor 0 1 区域的已使用的容量

ec eu 表示eden区域容量和已使用容量

mc mu metaspace元数据区的Commited Size   metaspace元数据区的使用大小

CCSC Compressed class 的Committed Size (压缩类空间) 调用的包太多, 调大CompressedClassSpaceSize即可
CCSU Compressed class的使用大小

oc ou 表示 老年区容量和已经使用的容量

PC PU 表示持久代的内存容量和已经使用的容量

YGC YGT 表示 新生代gc发生的次数  和耗时

FGC FULL GC的次数

FGCT 表示老年代FUll GC发生的次数和耗时

CGC 并发GC次数

CGCT 并发GC消耗的时间

GCT b表示总的GC耗时

上下文切换

针对频繁上下文问题,我们可以使用vmstat命令来进行查看

图片

cs(context switch)一列则代表了上下文切换的次数。

如果我们希望对特定的pid进行监控那么可以使用 pidstat -w pid命令,cswch和nvcswch表示自愿及非自愿切换。

图片

磁盘

磁盘问题和cpu一样是属于比较基础的。首先是磁盘空间方面,我们直接使用df -hl来查看文件系统状态

图片

更多时候,磁盘问题还是性能上的问题。我们可以通过iostat iostat -d -k -x来进行分析

图片

最后一列%util可以看到每块磁盘写入的程度,而rrqpm/s以及wrqm/s分别表示读写速度,一般就能帮助定位到具体哪块磁盘出现问题了。

另外我们还需要知道是哪个进程在进行读写,一般来说开发自己心里有数,或者用iotop命令来进行定位文件读写的来源。

图片

不过这边拿到的是tid,我们要转换成pid,可以通过readlink来找到pidreadlink -f /proc/*/task/tid/../..。

图片

找到pid之后就可以看这个进程具体的读写情况cat /proc/pid/io

图片

我们还可以通过lsof命令来确定具体的文件读写情况lsof -p pid

图片

 内存

free

堆内内存

内存问题大多还都是堆内内存问题。表象上主要分为OOM和StackOverflow。

OOM

JMV中的内存不足,OOM大致可以分为以下几种:

Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

这个意思是没有足够的内存空间给线程分配java栈,基本上还是线程池代码写的有问题,比如说忘记shutdown,所以说应该首先从代码层面来寻找问题,使用jstack或者jmap。如果一切都正常,JVM方面可以通过指定Xss来减少单个thread stack的大小。

另外也可以在系统层面,可以通过修改/etc/security/limits.confnofile和nproc来增大os对线程的限制

图片

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

这个意思是堆的内存占用已经达到-Xmx设置的最大值,应该是最常见的OOM错误了。解决思路仍然是先应该在代码中找,怀疑存在内存泄漏,通过jstack和jmap去定位问题。如果说一切都正常,才需要通过调整Xmx的值来扩大内存。

Caused by: java.lang.OutOfMemoryError: Meta space

这个意思是元数据区的内存占用已经达到XX:MaxMetaspaceSize设置的最大值,排查思路和上面的一致,参数方面可以通过XX:MaxPermSize来进行调整(这里就不说1.8以前的永久代了)。

Stack Overflow

栈内存溢出,这个大家见到也比较多。

Exception in thread "main" java.lang.StackOverflowError

表示线程栈需要的内存大于Xss值,同样也是先进行排查,参数方面通过Xss来调整,但调整的太大可能又会引起OOM。

 

使用JMAP定位代码内存泄漏

上述关于OOM和StackOverflow的代码排查方面,我们一般使用JMAPjmap -dump:format=b,file=filename pid来导出dump文件

图片

通过mat(Eclipse Memory Analysis Tools)导入dump文件进行分析,内存泄漏问题一般我们直接选Leak Suspects即可,mat给出了内存泄漏的建议。另外也可以选择Top Consumers来查看最大对象报告。和线程相关的问题可以选择thread overview进行分析。除此之外就是选择Histogram类概览来自己慢慢分析,大家可以搜搜mat的相关教程。

图片

日常开发中,代码产生内存泄漏是比较常见的事,并且比较隐蔽,需要开发者更加关注细节。比如说每次请求都new对象,导致大量重复创建对象;进行文件流操作但未正确关闭;手动不当触发gc;ByteBuffer缓存分配不合理等都会造成代码OOM。

另一方面,我们可以在启动参数中指定-XX:+HeapDumpOnOutOfMemoryError来保存OOM时的dump文件。

gc问题和线程

gc问题除了影响cpu也会影响内存,排查思路也是一致的。一般先使用jstat来查看分代变化情况,比如youngGC或者fullGC次数是不是太多呀;EU、OU等指标增长是不是异常呀等。

线程的话太多而且不被及时gc也会引发oom,大部分就是之前说的unable to create new native thread。除了jstack细细分析dump文件外,我们一般先会看下总体线程,通过pstreee -p pid |wc -l。

图片

或者直接通过查看/proc/pid/task的数量即为线程数量。

图片

堆外内存

如果碰到堆外内存溢出,那可真是太不幸了。首先堆外内存溢出表现就是物理常驻内存增长快,报错的话视使用方式都不确定,如果由于使用Netty导致的,那错误日志里可能会出现OutOfDirectMemoryError错误,如果直接是DirectByteBuffer,那会报OutOfMemoryError: Direct buffer memory

堆外内存溢出往往是和NIO的使用相关,一般我们先通过pmap来查看下进程占用的内存情况pmap -x pid | sort -rn -k3 | head -30,这段意思是查看对应pid倒序前30大的内存段。这边可以再一段时间后再跑一次命令看看内存增长情况,或者和正常机器比较可疑的内存段在哪里。

图片

我们如果确定有可疑的内存端,需要通过gdb来分析gdb --batch --pid {pid} -ex "dump memory filename.dump {内存起始地址} {内存起始地址+内存块大小}"

图片

获取dump文件后可用heaxdump进行查看hexdump -C filename | less,不过大多数看到的都是二进制乱码。

NMT是Java7U40引入的HotSpot新特性,配合jcmd命令我们就可以看到具体内存组成了。需要在启动参数中加入 -XX:NativeMemoryTracking=summary 或者 -XX:NativeMemoryTracking=detail,会有略微性能损耗。

一般对于堆外内存缓慢增长直到爆炸的情况来说,可以先设一个基线jcmd pid VM.native_memory baseline。

图片

然后等放一段时间后再去看看内存增长的情况,通过jcmd pid VM.native_memory detail.diff(summary.diff)做一下summary或者detail级别的diff。

图片

图片

可以看到jcmd分析出来的内存十分详细,包括堆内、线程以及gc(所以上述其他内存异常其实都可以用nmt来分析),这边堆外内存我们重点关注Internal的内存增长,如果增长十分明显的话那就是有问题了。

detail级别的话还会有具体内存段的增长情况,如下图。

图片

此外在系统层面,我们还可以使用strace命令来监控内存分配 strace -f -e "brk,mmap,munmap" -p pid

这边内存分配信息主要包括了pid和内存地址。

图片

不过其实上面那些操作也很难定位到具体的问题点,关键还是要看错误日志栈,找到可疑的对象,搞清楚它的回收机制,然后去分析对应的对象。比如DirectByteBuffer分配内存的话,是需要full GC或者手动system.gc来进行回收的(所以最好不要使用-XX:+DisableExplicitGC)。

那么其实我们可以跟踪一下DirectByteBuffer对象的内存情况,通过jmap -histo:live pid手动触发fullGC来看看堆外内存有没有被回收。如果被回收了,那么大概率是堆外内存本身分配的太小了,通过-XX:MaxDirectMemorySize进行调整。如果没有什么变化,那就要使用jmap去分析那些不能被gc的对象,以及和DirectByteBuffer之间的引用关系了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/799143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3解决:Mockjs 引入后并访问 404(Not Found) 的页面报错问题

1、问题描述: 其一、报错为: GET http://localhost:5173/list 404 (Not Found) ncaught (in promise) AxiosError {message: Request failed with status code 404, name: AxiosError, code: ERR_BAD_REQUEST, config: {…}, request: XMLHttpRequest,…

【C语言初阶】指针篇—上

目录 1. 指针是什么?2. 指针和指针类型2.1 指针-整数2.2 指针的解引用 3. 野指针3.1 野指针成因1. 指针未初始化2. 指针越界访问3. 指针指向的空间释放 3.2 如何规避野指针 1. 指针是什么? 指针是什么? 指针理解的2个要点: > 1…

DAY14_FilterListenerAjaxAxiosJsonfastjson综合案例-axios和html交互

目录 1 Filter1.1 Filter概述1.2 Filter快速入门1.2.1 开发步骤1.2.2 代码演示 1.3 Filter执行流程1.4 Filter拦截路径配置1.5 过滤器链1.5.1 概述1.5.2 代码演示1.5.3 问题 1.6 案例1.6.1 需求1.6.2 分析1.6.3 代码实现1.6.3.1 创建Filter1.6.3.2 编写逻辑代码1.6.3.3 测试并抛…

计算机组成原理问答7

外围设备 1. I/O设备 输入设备(鼠标、键盘)、输出设备(显示器、打印机)、外存设备(光盘、硬盘) 2. I/O接口 又称I/O控制器、设备控制器,负责协调主机与外部设备之间的数据传输。 I/O控制方式 3. 程序查询方式 中断 关中断作用:实现原子操作。屏蔽可屏蔽的中断。…

备战秋招 | 笔试强训16

目录 一、选择题 二、编程题 三、选择题题解 四、编程题题解 一、选择题 1、下列一段 C 代码的输出结果是&#xff08;&#xff09; #include <iostream> class Base { public:int Bar(char x){return (int)(x);}virtual int Bar(int x){return (2 * x);} }; clas…

如何启用路由器dhcp?快解析如何内网穿透?

一、什么是DHCP&#xff1f; 动态主机设置协议&#xff08;DHCP&#xff09;是一种使网络管理员能够集中管理和自动分配 IP 网络地址的通信协议。在网络中&#xff0c;每个联网设备都需要分配独有的 IP 地址。并当有新计算机移到网络中的其它位置时&#xff0c;能自动收到新的…

【阅读笔记】一种暗通道优先的快速自动白平衡算法

解决问题: 自动白平衡算法中存在白色区域检测错误导致白平衡失效的问题,作者提出了一种基于暗通道优先的白平衡算法。 算法思想: 图像中白色区域或者高饱和度区域的光线透射率较低,根据以上特性利用暗通道法计算图像中白色区域。 算法概述: 作者使用何凯明提出的基于暗…

MLP-Mixer:面向视觉的全mlp架构

文章目录 MLP-Mixer: An all-MLP Architecture for Vision摘要本文方法代码实验结果 MLP-Mixer: An all-MLP Architecture for Vision 摘要 卷积神经网络(cnn)是计算机视觉的首选模型。 最近&#xff0c;基于注意力的网络&#xff0c;如VIT&#xff0c;也变得流行起来。在本文…

四种刷题模式的爱刷题无后端无数据库刷题应用网站H5源码

四种刷题模式的爱刷题无后端无数据库刷题应用网站H5源码。提供了简单轻量化的部署方式和详细的四种刷题模式教程。该应用使用JSON作为题库的存储方式&#xff0c;层次清晰、结构简单易懂。 配套的word模板和模板到JSON转换工具可供使用&#xff0c;方便将题库从word格式转换为…

Python显示循环代码的进度条

目录 1. tqdm库 2. alive_progress库 3. progressbar库 1. tqdm库 tqdm是一个快速&#xff0c;可扩展的Python进度条&#xff0c;可以在Python长循环中添加一个进度提示信息 import time from tqdm import trangefor i in trange(100):# do somethingtime.sleep(0.5) 2. a…

Mysql原理篇--第一章 1条语句的执行

Mysql原理系列篇 第一章 1条语句的执行 文章目录 Mysql原理系列篇 第一章 1条语句的执行前言&#xff1a;1 连接mysql 服务端:1.1 通信模型&#xff1a;1.2 通信连接数&#xff1a; 2 sql 语句的到达存储引擎的流程:3 数据从存储引擎返回的流程&#xff1a;4 Buffer_pool 脏页的…

【云原生】Docker容器资源限制(CPU/内存/磁盘)

目录 ​编辑 1.限制容器对内存的使用 2.限制容器对CPU的使用 3.block IO权重 4.实现容器的底层技术 1.cgroup 1.查看容器的ID 2.在文件中查找 2.namespace 1.Mount 2.UTS 3.IPC 4.PID 5.Network 6.User 1.限制容器对内存的使用 ⼀个 docker host 上会运⾏若⼲容…

【Linux下6818开发板(ARM)】SecureCRT串口和交叉编译工具(巨细版!)

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…

策略:一致性行动原则,力出一孔

策略&#xff1a;一致性行动的原则 策略有很多种解释 经常跟战略混淆 趣讲大白话&#xff1a;就是指导方针 【趣讲信息科技238期】 **************************** 教员的游击战“16字口诀”很经典 敌进我退&#xff0c;敌退我进&#xff0c; 敌疲我打&#xff0c;敌驻我扰 曾国…

小城市当程序员好不好?

在职业发展中&#xff0c;小城市和大城市都有各自的机会和挑战。在大城市&#xff0c;C#的应用比例可能相对较低&#xff0c;学习C可能有一定的难度&#xff0c;而学习Java最好有人指导。在小城市&#xff0c;机会相对较少&#xff0c;跳槽的选择也有限。然而&#xff0c;小城市…

想转嵌入式或工控上位机,哪个前途更光明?

上位机开发的需求目前很大&#xff0c;根据BOSS上的数据&#xff0c;C#和WPF的需求较多。作为WPF开发者&#xff0c;薪资水平可以有较大的变动&#xff0c;主要取决于经验&#xff0c;20,000到30,000元的薪资并不难达到。工作环境因工种而异&#xff0c;不可避免地需要进行现场…

消息队列 - 数据库操作

这里写自定义目录标题 前言数据表的插入删除操作关于实现接口类的几个注意实现实现封装创建DataBaseManager 类另一种获取Bean对象的方式 对数据库进行单元测试 前言 上一篇博客, 我们将消息队列的实体类创建完毕了, 并且还写了一些关于数据库的操作, 接下来我们继续进行关于数…

【Spring Cloud Alibaba】Sentinel运行原理

文章目录 前言1、基本原理2、SphU.entry()2.1、StringResourceWrapper2.2、Entry 3、entry.exit()4、Context 前言 本文基于sentinel-1.8.0版本 Sentinel 是面向分布式服务架构的流量控制组件&#xff0c;主要以流量为切入点&#xff0c;从限流、流量整形、熔断降级、系统负载保…

fast segment anything

[论文解读]比sam快50倍的通用视觉模型fastsam(Fast Segment Anything) - 知乎MetaAI提出的能够“分割一切”的视觉基础大模型SAM提供了很好的分割效果&#xff0c;为探索视觉大模型提供了一个新的方向。 虽然sam的效果很好&#xff0c;但由于sam的backbone使用了vit&#xff0c…

Nexus上传jar包到私有Maven仓库的方法: 页面Upload 和命令

Upload和mvn deploy命令两种上传方式的应用场景不同&#xff0c;手动上传适用于工具类的jar包&#xff0c;比如项目需要引入的lib文件&#xff0c;这种可以选择手动上传。复杂的、有较多依赖的jar包则需要连同pom文件一起上传&#xff0c;此时需要使用mvn deploy。 登录Nexus&a…