ThreadLocal为什么会导致内存泄漏?

问题引出:
ThreadLocal是为了解决什么问题而产生的?
ThreadLocal发生内存泄漏的根本原因是什么?
如何避免内存泄漏的发生?

定义

  为了解决多个线程同时操作程序中的同一个变量而导致的数据不一致性的问题。
  假设现在有两个线程A和B,想要同时使用程序中的某个变量,如果想要保持这个变量的数据一致性,该怎么做?
(1)首先最直接的方法就是对变量进行加锁,一次只允许一个线程进行操作;但是这种加锁的方式效率不高,当有很多线程想要操作变量时,没有持有锁的线程只能等待。
(2)而Threadlocal解决的方式就比较优雅了,它是怎么做的呢?一句话概括:为每一个线程创建了变量的副本。
大白话解释:给两个线程分别分配了一个容器,线程在各自的容器中对各自的变量副本进行操作,互不影响,实现了线程之间的隔离。

类图

  在ThreadLocal的类中,存在一个核心的内部类ThreadLocalMap;在ThreadLocalMap的类中,也存在着一个核心的内部类Entry。
Threadllocal

图解

  对于每一个线程,都维护着自己的ThreadLocalMap,而这个ThreadLocalMap中存放的变量就是Entry类型的,Entry类型的变量的key就是一个threadLocal对象,value就是你想要存的值。如下图所示:
ThreadLocal图解

思考:
一个ThreadLocal对象是否可以对应多个值(Object v)?

内存泄漏

在宏观上,内存泄漏是指,由于错误或者疏忽,未能正确释放已经不再使用的内存。
那么ThreadLocal发生内存泄漏的根本原因是什么呢?
根本原因在于ThreadLocalMap中存的是一个个的Entry对象,问题就出在这个Entry对象中。

static class Entry extends WeakReference<ThreadLocal<?>> {/** The value associated with this ThreadLocal. */Object value;Entry(ThreadLocal<?> k, Object v) {super(k);value = v;}}

仔细看,Entry对象中的ThreadLocal变量是一个弱引用,这个倒没问题,jvm会在合适的时机将其内存自动进行回收;但是Entry对象中的Object值是一个强引用,问题就出现在这里,jvm宁愿报内存溢出的错,也不愿意主动去回收一个强引用的内存。
这就会出现一种什么情况呢?我的ThreadLocal变量的内存已经被jvm回收掉了,在ThreadLocalMap中已经不再需要以当前被回收掉的ThreadLocal变量为key的Entry了,但是这个Entry中的value一直得不到回收,因为它是一个强引用。由此发生了内存泄漏。

思考:ThreadLocal一定会发生内存泄漏吗?
答:不一定。解答此问题的关键在于要明白ThreadLocal的生命周期是和当前线程的生命周期是一样的。
如果当前线程被销毁了,那么线程中的所有变量都将被销毁,包括ThreadLocalMap对象、Entry对象等等;
如果当前线程没有被销毁,它只是被回收到线程池中了(比如当前线程是一个核心线程),则就会发生内存泄漏。

内存泄漏的避免

  在使用完ThreadLocal之后,调用它的remove方法,主动去清除不再使用的内存。

参考链接:
Threadlocal为什么会有内存泄漏泄漏,如何解决
java中的引用

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

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

相关文章

如何获取一个城市或者一个区域的玫瑰风向图?

玫瑰风向图是一种直观展示风向和风速的图形工具&#xff0c;它在气象学、城市规划、农业等领域都有广泛的应用。那么&#xff0c;如何获取某个城市或某个区域的玫瑰风向图呢&#xff1f; 首先&#xff0c;我们可以借助互联网资源获取玫瑰风向图。现代网络技术发达&#xff0c;…

前端 防抖和节流

在前端开发中&#xff0c;防抖&#xff08;Debounce&#xff09;和节流&#xff08;Throttle&#xff09;是两种常用的性能优化技术&#xff0c;尤其在处理频繁触发的事件时显得尤为重要。无论是在用户输入、窗口调整大小&#xff0c;还是滚动事件中&#xff0c;这两种技术都可…

3D 生成重建011-LucidDreamer 优化SDS过平滑结果的一种探索

3D 生成重建011-LucidDreamer 优化SDS过平滑结果的一种探索 文章目录 0论文工作1论文方法2 效果 0论文工作 文本到3D生成的最新进展标志着生成模型的一个重要里程碑&#xff0c;为在各种现实场景中创建富有想象力的3D资产打开了新的可能性。虽然最近在文本到3D生成方面的进展…

自建公式,VBA在Excel中解一元一次方程

自建公式,VBA在Excel中解一元一次方程 文章目录 前言一、运行效果图二、操作思路三、代码1.去除方程中未知数,将未知数转为“*0”2.计算方程中常数3.计算方程中未知数的系数一,先将未知数替换成“*1”4.计算方程中未知数的系数二5.计算方程得数前言 小学必考内容:一元一次…

掌握Python基本语法的终极指南【基本语法部分】

一、基本语法部分 1.简单数据类型 1.1字符串类型及操作 字符串访问&#xff1a; 1.索引访问 mystr"Hello world" #索引访问 print(mystr[0]) #H print(mystr[-1]) #d print(mystr[-7]) #o print(mystr[6]) #w 2.切片访问 [头下标&#xff1a;尾下标] &#x…

齐护K210系列教程(三十二)_在线模型训练

在线模型训练 概念理解准备工作1 采集图像1.1 图像要求1.2 使用K210采集图片 2 标注图像3 打包数据集4 上传数据4.1创建项目4.1.1图像分类创建项目4.1.2图像检测创建项目 4.2上传数据4.2.1分类检测上传数据4.2.2图像检测上传数据 5 训练模型6 部署模型以及测试7 测试效果7.1图像…

JDBC总结

目录 JDBC(java database connection) JDBC连接数据库步骤: 1. 在项目中添加jar文件,如图所示 2.加载驱动类 向数据库中插入数据代码示例: 第一种: 第二种: 查询操作 : 第一种: 第二种: JDBC(java database connection) java数据库连接.api(应用程序编程接口) ,可…

一文讲清!传统企业的进销存管理难题该怎么解决?

有没有开源的进销存软件啊&#xff1f; 确实&#xff0c;市面上存在不少开源的进销存软件。但客观地讲&#xff0c;开源软件往往面临着安全隐患&#xff0c;因为代码公开&#xff0c;容易成为黑客攻击的目标。此外&#xff0c;开源软件的功能模块通常较为固定&#xff0c;难以…

初出茅庐的小李博客之MQTT.fx客户端接入EMQX Platform

EMQX Platform 概览 EMQX Platform 是 EMQ 推出的一款面向物联网领域的 MQTT 消息中间件产品。作为全球首个 MQTT 5.0 消息云服务&#xff0c;EMQX Platform 提供了一站式运维代管、独有隔离环境的 MQTT 消息服务。在万物互联的时代&#xff0c;EMQX Platform 可以帮助您快速构…

python数据类型之列表

目录 1.创建列表 2.列表基础操作 常用操作 对列表元素顺序随机打乱 列表下标和切片 字符串分割为列表 列表位移 列表切片替换 3.列表内置方法 4.列表排序 简单排序 使用key参数按指定规则排序 二维列表排序 自定义排序规则函数 5.列表排序算法 选择排序 柱状图…

C# 利用Xejen框架源码,我们来开发一个基于Dapper技术的数据库通用的帮助访问类,通过Dapper的增删改查,可以访问Sqlite数据库

Dapper 是一个轻量级的对象关系映射&#xff08;ORM&#xff09;工具&#xff0c;适用于 .NET 平台。它由 Stack Overflow 团队开发&#xff0c;旨在提供简单、高效的数据访问功能。与其他重量级 ORM&#xff08;如 Entity Framework&#xff09;相比&#xff0c;Dapper 更加轻…

基于Python图像增强算法:低光增强+图像修复+超分辨率重建

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 在图像处理与计算机视觉领域&#xff0c;图像增强技术是提高图像质量和可用性的重要手段。在实…

单片机io扩展

输入输出扩展 i2c扩展 方案1:PCF8575 PCF8575双向IO口扩展模块 16位输入输出I2C通讯 单片机级联扩展板 方案2&#xff1a;PCA955A 输出扩展 74HC595 io口扩展模块输出口扩展 参考链接 中微爱芯发[2004] 1号           签发人&#xff1a; (szlcsc.com)https://…

❤ Vscode和Idea都可以使用的-AI插件(官方-百度出的)

❤ Vscode和Idea都可以使用的-AI插件&#xff08;官方-百度出的&#xff09; 最新AI特别火&#xff0c;给大家推荐一下最新出的VScode插件&#xff0c;辅助我们写代码&#xff01; 1、下载地址&#xff1a; > https://comate.baidu.com/zh/shopping?inviteCodefkzlak8f …

jmeter中Ultimate Thread Group设计梯度压测场景

Ultimate Thread Group Ultimate Thread Group 线程组是模拟波浪式压测或者阶梯式负载压测 1、Start Threads Count&#xff1a;线程数量 2、Initial Delay&#xff0c;sec&#xff1a;每组开始添加到测试执行之前的延迟&#xff08;xx秒开始启动线程&#xff09; 3、Startu…

python中的线程并行

文章目录 1. 单线程2. 线程池ThreadPoolExecutor 1. 单线程 现在有1154张图片需要顺时针旋转后保存到本地&#xff0c;一般使用循环1154次处理&#xff0c;具体代码如下所示&#xff0c;img_paths中存储1154个图片路径&#xff0c;该代码段耗时约用97ms。 t1time.time() for …

Python筑基之旅-MySQL数据库(四)

目录 一、数据表操作 1、新增记录 1-1、用mysql-connector-python库 1-2、用PyMySQL库 1-3、用PeeWee库 1-4、用SQLAlchemy库 2、删除记录 2-1、用mysql-connector-python库 2-2、用PyMySQL库 2-3、用PeeWee库 2-4、用SQLAlchemy库 3、修改记录 3-1、用mysql-conn…

Java轻松转换Markdown文件到Word和PDF文档

Markdown 凭借其简洁易用的特性&#xff0c;成为创建和编辑纯文本文档的常用选择。但某些时候我们需要更加精致的展示效果&#xff0c;例如在专业分享文档或打印成离线使用的纸质版时&#xff0c;就需要将Markdown文件以其他固定的文档格式呈现。通过将 Markdown 转换为 Word 和…

OpenHarmony实战开发——网络组件axios可以在OpenHarmony上使用了

什么是axios 上古浏览器页面在向服务器请求数据时&#xff0c;因为返回的是整个页面的数据&#xff0c;页面都会强制刷新一下&#xff0c;这对于用户来讲并不是很友好。并且我们只是需要修改页面的部分数据&#xff0c;但是从服务器端发送的却是整个页面的数据&#xff0c;十分…

高效写代码java-推荐插件1(格式转化 ConverterX )-日后待更新

ConverterX 主要功能:格式转化 字符串格式转换 日期转换 Json格式转义 字符格式 快捷键 ctrl shiftS Upper(CODEEASE)字符串全部变成大写Lower(codeease)字符串全部变成小写Camel(codeEase)字符串变成小驼峰ClassCaemel(CodeEase)字符串变成大驼峰UnderlineUpper(CODE_EAS…