JVM 内存溢出排查

说明:记录一次JVM内存溢出的排查过程;

场景

项目开发完成后,首次提交到测试环境。测试、产品同事反馈页面先是操作响应慢,抛出超时异常,最后直接无法使用。查看日志后得知是内存溢出

在这里插入图片描述

重启服务后,我对前端主要的几个长RT接口,使用Arthas进行了trace

在这里插入图片描述

排查

Step1:SQL问题

锁定到了时间主要消耗在一次数据库操作,首先想到这段SQL是否有问题。

在这里插入图片描述

但我把SQL单独取出来,拼接参数执行,时长非常短,不应该啊。

在这里插入图片描述

Step2:拦截器

这期间,我做了很多尝试,看了很多JVM内存溢出的文章,但是基本没有帮助。于是,我换了一种思路,项目重启后,疯狂调用慢接口,然后使用Arthas的dashboard命令,查看是否有异常的进程,结果如下:

在这里插入图片描述

可以看到有进程被阻塞了,再使用thread id命令,查看该进程情况,如下:

在这里插入图片描述

从上往下看,找到自己项目中的代码,按图索骥,我找到项目中的下面这段代码。这段代码在拦截器类里,拦截器是对操作数据库拼接参数、封装结果集时进行拦截操作,该段代码是封装结果集时会执行的。

	Cipher cipher = Cipher.getInstance(algorithmName, getSingleInstance());

问题可能出现在操作数据库,拦截器操作返回结果集的这一步,我先对该方法进行追踪,如下:

在这里插入图片描述

很明显,问题出在这里,每条记录耗时大几百毫秒,十条记录就是大几秒;

Step3:单例对象

	Cipher cipher = Cipher.getInstance(algorithmName, getSingleInstance());

回过头来,再分析这行代码。该方法是jdk提供的,应该没啥问题,重点是参数列表中的第二个方法getSingleInstance(),该方法写在该类里,是成员方法,目的是创建单例对象作为参数。查看该成员方法,代码如下(已脱敏)

	private static synchronized SingleBean getSingleInstance() {SingleBean single = null;if(single == null){single = new SingleBean();}return single;}

该代码看上去怪怪的,单例对象不应该这么创建。于是我将代码修改成如下,即单例创建模式之一的双重检查锁定:

	private static volatile SingleBean single = null;private ThisClass() {}/*** 创建单例对象*/private static SingleBean getSingleInstance() {if(single == null){synchronized (ThisClass.class) {if(single == null){single = new SingleBean();}}}return single;}

修改完之后,再调用一次接口,结果如下:

在这里插入图片描述

Nice!就是这个单例对象创建的问题。

复盘

这个问题,前前后后花了一整天的时间,从早上搞到晚上,最终解决,简单复盘一下,分为代码问题,其他问题;

代码

	private static synchronized BouncyCastleProvider getSingleInstance() {BouncyCastleProvider provider = null;if(provider == null){provider = new BouncyCastleProvider();}return provider;}

这段创建单例对象的代码,经分析可知:

  • static:导致了创建的对象不会被JVM回收;

  • synchronized:导致了线程的阻塞;

  • 错误的创建方式:导致每次查询都会创建大量的对象(每查一条记录就创建一个);

综合结果,就是JVM内存溢出,系统越用越慢,最终崩溃。

其他

其他原因来自两方面,场外因素和自身原因。

  • 场外因素:本身项目进度紧张,刚上测试,问题就提了一堆,而我们一个JVM溢出问题就搞了一天,产品同事也慌了,当天开了两次碰头面,又压缩了我们解决问题的时间。当时真有点“软件危机”的感觉。

  • 自身原因:排查思路开始有问题,因为页面上并不是所有接口都慢,大部分是正常的。所以我分析是两个问题,一个是慢接口,一个是导致系统崩溃的JVM内存溢出的问题,应该要优先解决后者。没想到这两个是同一个问题。另外,就是被java.lang.OutOfMemoryError唬住了,总感觉是非常不容易发现的问题,搞得我们还去找JVM的视图化工具,看JVM相关参数,除了知道溢出了毫无帮助。

另外

在解决问题过程中,学会了一些JVM相关的命令和工具,在这里Mark一下;

JVM视图工具

JDK自带视图化工具,如果你安装了JDK,可在CMD窗口敲下面的命令打开;

在这里插入图片描述

打开后,可查看Java进程相关的JVM参数,也支持远程连接,当然需要远程那边运行Java时配置相关参数,还需要主机可被访问;

在这里插入图片描述

JVM 内存泄漏排查

参考下面这篇文章,当时也敲了一些命令来排查问题。

  • Java诊断工具-Arthas保姆级教程

当时,我对测试环境项目敲了下图的代码,确实可以发现FGC频繁,且时长越来越长;

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

苹果开发者账号注册后生成开发证书和发布证书的流程解析

转载:注册苹果开发者账号的方法 在2020年以前,注册苹果开发者账号后,就可以生成证书。 但2020年后,因为注册苹果开发者账号需要使用Apple Developer app注册开发者账号,所以需要缴费才能创建ios证书了。 所以新政策出…

使用kubeadm工具搭建Kubernetes集群

本文目录 一、CentOS7最小化安装(master)1、下载ISO镜像2、安装3、进入centos安装界面4、安装最小化安装必要的一些工具 二、克隆虚拟机(node1、node2)三、基础配置1、节点规划——部署架构图2、防火墙和SElinux配置2、主机名和ho…

关于不同AR(增强现实)SDK(软件开发工具包)的汇总和特性描述

以下是每个AR SDK的核心内容概述: ARCore 开发者:Google支持平台:Android(部分设备不支持)功能:运动追踪、平面追踪、点云图、云锚点、光照估计、环境探针、人脸追踪、2D图片追踪、人物遮挡、射线测试。官网链接:ARCoreARKit 开发者:Apple支持平台:iOS(iPhone和iPad)…

2024年最新版FL Studio21.2.3 Build 4004 for Mac 版激活下载和图文激活教程

FL studio21中文别名水果编曲软件,是一款全能的音乐制作软件,包括编曲、录音、剪辑和混音等诸多功能,让你的电脑编程一个全能的录音室,它为您提供了一个集成的开发环境,使用起来非常简单有效,您的工作会变得…

合并两个单链表

归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言​📝 但行前路,不负韶华&#…

环信IM集成教程——Web端UIKit快速集成与消息发送

写在前面: 千呼万唤始出来,环信Web端终于出UIKit了!🎉🎉🎉 文档地址:https://doc.easemob.com/uikit/chatuikit/web/chatuikit_overview.html 环信单群聊 UIKit 是基于环信即时通讯云 IM SDK 开…

微信小程序自定义弹窗组件

业务背景&#xff1a;弹窗有时字体较多&#xff0c;超过7个字&#xff0c;不适用wx.showToast. 组件代码 <view class"toast-box {{isShow? show:}}" animation"{{animationData}}"><view class"toast-content" ><view class&q…

2024总结的vue3的面试题

一、vue2和vue3的区别 答案&#xff1a; 1、数据绑定原理不同 vue2&#xff1a;vue2的数据绑定是利用ES5的一个API&#xff1a;Object.definePropert() 对数据进行劫持&#xff0c;结合发布订阅模式的方式来实现的。 vue3&#xff1a;vue3中使用了ES6的Proxy API对数据代理…

大数据学习第十二天(hadoop概念)

1、服务器之间数据文件传递 1&#xff09;服务器之间传递数据&#xff0c;依赖ssh协议 2&#xff09;http协议是web网站之间的通讯协议&#xff0c;用户可已通过http网址访问到对应网站数据 3&#xff09;ssh协议是服务器之间&#xff0c;或windos和服务器之间传递的数据的协议…

ubuntu-server部署hive-part4-部署hive

参照 https://blog.csdn.net/qq_41946216/article/details/134345137 操作系统版本&#xff1a;ubuntu-server-22.04.3 虚拟机&#xff1a;virtualbox7.0 部署hive 下载上传 下载地址 http://archive.apache.org/dist/hive/ apache-hive-3.1.3-bin.tar.gz 以root用户上传至…

UE4 方块排序动画

【动画效果】 入动画&#xff1a; 出动画&#xff1a; 【分析】 入动画&#xff1a;方块动画排序方式为Z字形&#xff0c;堆砌方向为X和Y轴向 出动画&#xff1a;方块动画排序方式为随机 【关键蓝图】 1.构建方块砌体 2.入/出动画

wife_wife【web 攻防世界】

大佬的wp:WEB&#xff1a;Wife_wife-CSDN博客 知识点&#xff1a; prototype是new class 的一个属性&#xff0c;即__proto__指向new class 的prototype属性__proto__如果作为json代码解析的话会被当成键名处理&#xff0c;但是如果是在类中的话则会被当成子类的原型 如let o…