记一次TheadLocal使用方式不正确导致内存泄漏问题的排查和修复过程

news2024/11/7 18:13:07

一、背景

  一个部门其他同事的上线了很久的项目近期频繁的内存溢出——几乎每天内存溢出一次,而且频率越来越高。在添加了进程守护之后,虽然可以在内存溢出后自动重启,但并没有解决内存溢出的问题。不甘其扰之后,决定仔细排查导致内存溢出的根本原因。

二、排查过程

  在将内存溢出的dump文件导出之后,通过Jprofiler进行分析,发现HashMap对象占用的内存很大,而且一直在增加。
  就在代码里面查询创建全局HashMap对象的地方,发现有一个地方使用了ThreadLocal,代码如下:

private static final ThreadLocal<Map<Class<?>,Unmarshaller>> uMapLocal = new ThreadLocal<Map<Class<?>,Unmarshaller>>(){
	@Override
	protected Map<Class<?>, Unmarshaller> initialValue() {
		return new HashMap<>();
	}
};

  这是一个微信回调时会使用的Map,往这个Map里面put数据的代码如下:

public static <T> T convertToObject(Class<T> clazz,Reader reader){
	try {
		Map<Class<?>, Unmarshaller> uMap = uMapLocal.get();
		if(!uMapLocal.containsKey(clazz)){
			JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
			Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
			uMapLocal.put(clazz, unmarshaller);
		}
		return (T) uMapLocal.get(clazz).unmarshal(reader);
	} catch (JAXBException e) {
		e.printStackTrace();
	}
	return null;
}

  代码的本意是想避免对象的多次反序列化,想将已经反序列化过的对象放在一个全局的Map里面,下次如果这个Map中已经有了该对象就直接从Map里面获取,若没有则先将该对象反序列化之后置入这个Map中,再从该Map中获取。但他忽视了一点,这个HashMap是ThreadLocal的,微信在回调的时候每次都会新起一个线程,所以每次都会新创建一个HashMap对象。这就会导致内存泄漏。

三、修复

  将原来创建全局HashMap的地方的ThreadLocal去掉即可:

private static final Map<Class<?>,Unmarshaller> uMapLocal = new HashMap<>();

四、TheadLocal的使用

  ThreadLocal类型的变量从其命名上就可以知晓它是和线程有关的,每个线程各持有一份,并不是使用static修饰就变成了全局变量了。在使用的使用一定要注意clear。另外ThreadLocal类型的变量从一定意义上来说是可以用局部变量替换的,如果对ThreadLocal的原理不是很了解,最好不要使用,使用不当就可能导致内存泄漏问题。

五、排查过程中使用的工具和命令

  上面将问题排查、定位的过程极大的简化了。下面说一下具体的排查、定位和解决的详细过程。
  第一次该同事找我排查的时候,我将dump文件下载下来通过Jprofiler进行分析,显示是HashMap的内存占用很高,但HashMap对象并不是项目中定义的一个对象,并不好排查是哪个地方创建的HashMap。又再通过Jprofiler查看宕机时的线程的情况,定位到了出现问题的线程,然后查看代码,发现代码中有一个使用流的地方,但这个流在使用完之后没有关闭,就误以为是流未关闭导致的。在第一次修复时只是将这个流close掉了。
  后来该同事跟我说没有解决问题,还是每天内存溢出。于是就安装了arthas,在生产环境的服务器上使用arthas工具的dashboard观察,发现每次minorgc之后老年代的内存都会增加1到2M的内存,我就意识到应该是有地方内存泄露了。
请添加图片描述
  又查看当前堆内存中对象的创建情况:

jmap -histo:live 24353 >> /abc_class.log

  结果和使用Jprofiler查看的一致,HashMap对象的数量惊人的庞大:
请添加图片描述
  起初以为是项目中创建了一个全局的HashMap,然后不停的往该HashMap中put对象导致的。于是又从代码中找全局的HashMap,全部找出来之后没有发现存在一直向某个HashMap中put对象的问题。
  再看上面的截图中,发现是HashMap对象自身的实例个数庞大,而不是一个HashMap的内存庞大,也就是说有一个地方在一直创建HashMap实例,但这个HashMap肯定不是简简单单的局部变量,因为局部变量在栈调用结束之后是可以被回收的。
  最终终于找到了这个ThreadLocal的HashMap,解决了问题。

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

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

相关文章

C++string的模拟实现

CSDN的uu们&#xff0c;大家好。这里是C入门的第十六讲。 座右铭&#xff1a;前路坎坷&#xff0c;披荆斩棘&#xff0c;扶摇直上。 博客主页&#xff1a; 姬如祎 收录专栏&#xff1a;C专题 目录 1. string类的成员变量 2. 构造函数 3. 析构函数 4. const char* c_str(…

ESP32网络开发实例-连接信号最强的热点

连接信号最强的热点 文章目录 连接信号最强的热点1、软件准备2、硬件准备3、代码实现在本文中,将向您展示如何使用 ESP32 WiFiMulti 库。 这使我们能够使用多个网络,ESP32 可以连接到列表中可用的最强 WiFi 网络。 每当它失去连接时,它都会重新连接到列表中下一个最强的网络…

数据结构-----图(Graph)论必知必会知识

目录 前言 图的基本概念 1.什么是图&#xff1f; 2 .图的相关术语 3 .有向图和无向图 4.简单图和多重图 5.连通图、强连通图、非连通图 6.权与网 7.子图和(强)连通分量 8.生成树和生成森林 前言 今天我们学习一种新的数据结构-----图&#xff0c;大家在日常生活中经常都…

KingBase用户与角色及对象访问权限(Kylin)

用户与角色 角色的概念 将一组具有相同权限的用户组织在一起&#xff0c;这一组具有相同权限的用户就称为角色&#xff08;Role&#xff09;角色在生产系统中一般被视为用户组&#xff0c;利用角色对用户进行批量授权 创建用户角色 CREATE USER name WITH [option]授予权限…

理解内存,让Android性能没有问题

内存优化一直是一个很重要但却缺乏关注的点&#xff0c;内存作为程序运行最重要的资源之一&#xff0c;需要运行过程中做到合理的资源分配与回收&#xff0c;不合理的内存占用轻则使得用户应用程序运行卡顿、ANR、黑屏&#xff0c;重则导致用户应用程序发生 OOM&#xff08;out…

Sarscape5.6版本中导入外部控制点、写入精密轨道文件与GACOS用于大气相位

SARscape中导入外部GCP点用于轨道精炼 https://www.cnblogs.com/enviidl/p/16524645.html在SAR处理时&#xff0c;有时会加入GCP点文件&#xff0c;SAR处理中用到的控制点分为两类&#xff1a;用于校正地理位置的几何控制点&#xff08;Geometry GCP&#xff09;和用于轨道精炼…

C++类和对象(三) (this指针)

this指针 1 this指针的引出 我们先来定义一个日期类 Date class Date { public:void Init(int year, int month, int day){_year year;_month month;_day day;}void Print(){cout << _year << "-" << _month << "-" << …

【电子通识】USB接口三大类型图册

基本概念 不同时期的USB接口有不同的类型&#xff0c;USB接口分为插头和插座&#xff1a; 插头&#xff0c;plug&#xff0c;对应的也叫公口&#xff0c;即插别人的。 插座&#xff0c;receptacle&#xff0c;对应也叫做母口&#xff0c;即被插的。 USB的接口类型&#xff0…

《动手学深度学习 Pytorch版》 9.6 编码器-解码器架构

为了处理这种长度可变的输入和输出&#xff0c; 可以设计一个包含两个主要组件的编码器-解码器&#xff08;encoder-decoder&#xff09;架构&#xff1a; 编码器&#xff08;encoder&#xff09;&#xff1a;它接受一个长度可变的序列作为输入&#xff0c;并将其转换为具有固定…

模拟器-雷电-使用adb push或adb pull操作文件

一、环境 windows 10 雷电模拟器4.0.83 二、问题 有时候我们会需要往模拟器拷贝文件或者复制文件到我的电脑 三、方法 1、获取root权限 adb root adb remount 有可能遇到【daemon not running; starting now at tcp:5037】的报错 查看端口占用进程&#xff1a;netstat -…

vue2升级到vue2.7

vue2升级到vue2.7 小小的改进,大大的提升 只需要简单修改,开发体验得到大大提升. 为什么要升级Vue2.7 不能拒绝的理由: 组合式 API(解决mixins问题:命名冲突,隐式依赖)单文件组件内的 <script setup>语法模板表达式中支持 ESNext 语法(可选链:?.、空值合并:??)单文…

域渗透05-协议(NTLM)

前言&#xff1a; 首先在域内环境中主要有如下6种身份认证协议&#xff0c;最常用的还是Kerberos&#xff0c;NTLM和LDAP三种&#xff1a; Kerberos&#xff1a;Kerberos是一种网络身份验证协议&#xff0c;用于验证用户和服务之间的身份。它通过使用票据和密钥来实现认证&…

Linux 指令学习

Linux 指令学习 以此为记录&#xff0c;也方便自己日后查看回顾&#xff01; Linux命令基础格式 无论是什么命令&#xff0c;用于什么用途&#xff0c;在Linux中&#xff0c;命令有其通用的格式&#xff1a; command&#xff1a; 命令本身 options&#xff1a;[可选&#xf…

AD9371 官方例程

文章目录 前言一、HDL方面1. ZYNQ 核根据ZCU106平台修改&#xff08;**参考UG1244 ZCU106 Evaluation Board**&#xff09;&#xff0c;尤其注意**DDR**的配置&#xff08;**参考美光 MTA4ATF51264HZ**&#xff09;2.dacfifo 深度 要修改 &#xff0c;地址位宽 小于等于16&…

Windows 11 2023 Moment 4 更新内容详解

Windows 11 2023 Moment 4 更新内容详解 编辑&#xff1a;简简单单 Online zuozuo 地址&#xff1a;https://blog.csdn.net/qq_15071263 前言 主要的更新内容清单 Copilot内置应用资源管理器照片应用截图工具画图与视频剪辑Windows 备份系统界面开始菜单快速设置系统托盘任务…

【python】进程和线程

进程和线程 今天我们使用的计算机早已进入多CPU或多核时代&#xff0c;而我们使用的操作系统都是支持“多任务”的操作系统&#xff0c;这使得我们可以同时运行多个程序&#xff0c;也可以将一个程序分解为若干个相对独立的子任务&#xff0c;让多个子任务并发的执行&#xff…

优测云测试平台 | 有效的单元测试

一、前言 本文作者提出了一种评价单元测试用例的质量的思路&#xff0c;即判断用例是否达到测试的“四大目标”。掌握识别好的用例的能力&#xff0c;可以帮助我们高效地写出高质量的测试用例。 评判冰箱的好坏&#xff0c;并不需要有制造一台冰箱的能力。在开始写测试用例之…

TikTok Shop印尼站关停,跨境卖家该如何自救

10.4日&#xff0c;TikTok Shop宣布关停印尼站&#xff0c;无疑是一个巨大的炸弹投在整个跨境圈&#xff0c;让许多跨境卖家以及当地本土的卖家、品牌措手不及。 这对TikTok的东南亚市场而言&#xff0c;无疑是一次沉重的打击。 TikTok在东南亚的商业布局&#xff0c;印尼是其…

小A对我说,他现在快想钱想疯了…

昨天晚上11点&#xff0c;小A给我打电话 小A问&#xff1a;橙哥&#xff0c;有没有赚钱的事做&#xff1f; 他说&#xff0c;实在不想上班了&#xff0c;每天起早贪黑挤地铁 辛辛苦苦干一个月&#xff0c;到手工资三四千块钱&#xff0c;房租一交&#xff0c;日常开支一花&a…

Jmeter安装(快速入门)

大家好我是苏麟今天简单聊一下Jmeter . Jmeter Jmeter官网 : Apache JMeter - Download Apache JMeter 安装Jmeter Jmeter依赖于JDK&#xff0c;所以必须确保当前计算机上已经安装了JDK&#xff0c;并且配置了环境变量。 下载 : 官网下载 : 网盘自取 : 链接&#xff1a;…