ThreadLocal内存泄漏问题

news2024/7/6 18:28:52

引子:

内存泄漏:是指本应该被GC回收的无用对象没有被回收,导致内存空间的浪费,当内存泄露严重时会导致内存溢出。Java内存泄露的根本原因是:长生命周期的对象持有短生命周期对象的引用,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被GC回收。

内存溢出:就是我们常说的OOM(OutOfMemoryError)异常,简单理解就是内存不够了,通常发生在程序申请的内存超出了JVM中可用内存的大小,就会抛出OOM异常。在JVM内存区域中,除了程序计数器外其他的内存区域都有可能抛出OOM异常。

ThreadLocal很好地解决了线程之间需要数据隔离的问题,同时也引入了另一个问题,在应用程序中通常会使用线程池来管理线程,那么线程的生命周期与应用程序的生命周期基本保持一致,如果线程的数量很多,随着程序的运行,时间的推移,ThreadLocal类型的变量会越来越多,将会占用非常大的内存空间,从而产生内存泄漏,如果这些对象一直不被释放的话,可能会导致内存溢出。

 

大家先看一下内存图:

 

从图中可以看出,ThreadLocal对象存在于堆中,有栈中的强引用指向它,也有ThreadLocalMap中的entry的弱引用键指向他。

“弱引⽤:只要垃圾回收机制⼀运⾏,不管JVM的内存空间是否充⾜,都会回收该对象占⽤的内存。”

而随着程序的运行,栈中ThreadLocal的强引用会消亡,只剩下弱引用连接着ThreadLocal独享,由于ThreadLocalMap.Entity中的key是弱引用,所以堆中的ThreadLocal对象会被回收(只要发生GC,弱引用对象就会被回收),但是ThreadLocalMap⽣命周期和Thread是⼀样的,它这时候如果不被回收,就会出现这种情况:ThreadLocalMap的key没了,value还在,这就会造成了内存泄漏问题(由弱引用引起的内存泄漏)。

而对于线程来说,线程的生命周期与应用程序的生命周期基本保持一致,所以一直会存在:Current Thread Refefence -> Thread -> ThreaLocalMap -> Entry -> value -> Object的强引用,这样value所强引用的Object对象迟迟得不到回收,就会导致内存泄漏。

如何解决弱引用导致的内存泄露问题?

ThreadLocalMap的设计中已经考虑到这种情况,所以ThreadLocal的get()、set()、remove()的时候都会清除线程ThreadLocalMap里所有key为null的value。

一旦将value设置为null之后,就斩断了引用与真实内存之间的强引用,就能够真正的释放空间,防止内存泄漏。

但是这只是一种被动的方式,如果这些方法都没有被调用怎么办?那你就每次使用完ThreadLocal变量之后,执行remove方法。

总结:ThreadLocalMap中的弱引用以及调用ThreadLocal各种方法后的清理只是增加了一层防护手段,还是有可能会导致内存泄露,真正想防止内存泄漏,需要编码的规范,使用完ThreadLocal后,及时调用remove()方法释放内存空间。

 

那为什么还要维持一个弱引用呢?

设置ThreadLocal对象的弱引用,这样做的目的是确保ThreadLocal对象在没有其他强引用时可以被垃圾回收。

key设计成弱引⽤同样是为了防⽌内存泄漏(这是另一个原因引起的内存泄漏)。假如key被设计成强引⽤,如果ThreadLocal Reference被销毁,此时它指向ThreadLoca的强引⽤就没有了,但是此时key还强引⽤指向ThreadLoca,就会导致ThreadLocal不能被回收,这时候就发⽣了内存泄漏的问题。

两个内存泄漏问题是不一样的

  • 这里是ThreadLocal变量无法被回收,导致内存泄漏;

  • 而弱引用导致的则是Value指向的object无法被回收,导致内存泄漏;

总结

首先,如果让key使用强引用指向ThreadLocal,则ThreadLocal对象无法被回收,导致内存泄漏;为了解决这个问题,让key使用弱引用指向Threadlocal,而这也会导致了Value无法被回收,造成内存泄漏,如何解决呢?我们在使用完ThreadLocal对象后,及时使用remove方法释放内存空间即可。

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

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

相关文章

为什么 ThreadLocal 会导致内存泄漏 ?如何解决 ?

面试官问 :为什么 ThreadLocal 会导致内存泄漏 ?? 在面试中被问到这个问题,如果记不清细节了,可以这样回答: ThreadLocal 里面存储的数据,它的生命周期是和线程或者线程池的生命周期保持一致的…

JavaWeb-DAO设计模式

目录 DAO设计模式 1.认识DAO 2.DAO各部分的详解 3.DAO设计模式流程 DAO设计模式 1.认识DAO DAO(Data Acess Object 数据库访问对象)的主要功能是操作数据库,所以DAO在标准开发架构中数据数据层,以下是标准开发的架构 客户层:目前使用B/…

ZKSV2-12-2NCP、ZKSV2-08-2NCSP-L、ZKSV2-08-2NOP插装式电磁换向阀

ZKSV-08-2NCP、ZKSV2-08-2NCP、ZKSV2-10-2NCP、ZKSV2-12-2NCP、ZKSV2-08-2NCSP-L、ZKSV2-08-2NOP、ZKSV2-10-2NOP、ZKSV2-12-2NOP、ZKSV2-08-3、ZKSV2-08-3A、ZKSV2-08-3C、ZKSV2-08-3B、ZKSV2-10-3、ZKSV2-10-3C、ZKSV2-10-3B、ZKSV2-08-4 CO、ZKSV2-08-4 NC、ZKSV2-08-4 TC、…

问道管理:机器人概念走势活跃,新时达涨停,拓斯达、丰立智能等大涨

机器人概念17日盘中走势活跃,到发稿,拓斯达大涨18%,昊志机电涨近16%,丰立智能涨超13%,步科股份、优德精细涨超10%,新时达涨停,天玑科技、兆龙互联、中大力德涨逾9%。 消息面上,8月16…

javaScript:一分钟看懂数组排序以及冒泡排序(重点)

目录 一.前言 二.数组排序 sort() 字符串大小的比较原则 字符编码排序规则 如果使用sort从小到大排列 (重点) 函数的返回值 规则: 代码 案例 数组打乱 sort相关代码 三.冒泡排序(重点&#xff…

Zass主题 - 手工艺术家和工匠的WooCommerce商城主题

Zass主题是适合手工艺术家和工匠的完美 WordPress / WooCommerce 主题。无论您是想为您的手工制作业务构建功能齐全的 Etsy Style 在线商店、博客还是作品集,Zass 主题都是您的正确选择。凭借其极其强大的自定义电子商务功能、无限的作品集风格、不同的博客风格和无…

多维时序 | MATLAB实现WOA-CNN-GRU-Attention多变量时间序列预测

多维时序 | MATLAB实现WOA-CNN-GRU-Attention多变量时间序列预测 目录 多维时序 | MATLAB实现WOA-CNN-GRU-Attention多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现WOA-CNN-GRU-Attention多变量时间序列预测,WOA-CNN-GR…

小象课堂在线授课教育系统

此项目包含后端全部代码,前端包括后台和web界面的源码,数据库用的mysql,可当作课设或者毕设,还可写入自己的简历中 web界面展示: 前端后台界面展示: 用户管理 课程管理 内容配置 订单管理 系统管理 系统监控

Postman项目实战一

项目简介:外卖任务委派系统 测试脚本: 登录,获取token创建任务,获取任务id根据id,修改任务根据id,查询任务根据id,删除任务根据id,验证任务已被删除 步骤: 1.创建Col…

聚隆转债上市价格预测

聚隆转债 基本信息 转债名称:聚隆转债,评级:A,发行规模:2.185亿元。 正股名称:南京聚隆,今日收盘价:16.64元,转股价格:18.27元。 当前转股价值 转债面值 / 转…

炒股票怎么加杠杆_融资融券账户怎么开通

炒股票作为一种投资方式,可以带来不错的回报。然而,对于那些希望以较小的资金获得更高收益的投资者来说,加杠杆炒股票是一个值得考虑的选择。本文将为您介绍加杠杆炒股票的意义,以及如何开通融资融券账户。 加杠杆炒股票的意义&a…

vue常识

vue是一套用于构建用户界面的渐进式框架,vue的核心库只关注视图层 1.声明式框架 ● 早在jquery的时期,编写代码都是命令式的,命令式框架的特点就是关注过程 ● 声明式框架更加注重结果,命令式的代码封装到了vue.js中,过程靠vue.js来实现 声明式代码更加简单,不需要关注实现,…

ssm学生请假系统源码和论文

ssm学生请假系统034 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集…

知了汇智与西南石油大学合作开展网络安全生产实习,培养实战型人才

近年来,随着互联网的快速发展和数字化转型的推进,网络安全问题日益突出。然而,网络安全应用型人才的供给却严重不足,导致行业面临着巨大的挑战和风险。面对这一现状,开展校企合作,培养优秀的网络安全行业人…

Talk | ICCV‘23 HumanMAC:简洁易拓展的人体动作预测新框架

​ 本期为TechBeat人工智能社区第522期线上Talk! 北京时间8月16日(周三)20:00,清华大学博士生—陈凌灏的Talk已准时在TechBeat人工智能社区开播! 他与大家分享的主题是: “HumanMAC-简洁易拓展的人体动作预测新框架”,介绍了人体动…

使用爱校对提升公文材料准确性的必要性

在我们的工作中,公文材料的准确性往往决定了我们的工作效果。无论是内部的报告、计划,还是外部的公告、通知,都需要准确无误才能达到我们预期的效果。为此,我们需要使用强大的工具——爱校对,来提升公文材料的准确性。…

Yii2 advanced 框架,自定义Log日志方案

背景 近期在使用 【Yii2 advanced】框架时 在接触到 微信支付回调操作时,想要将微信服务器请求的参数信息记录下来 但是,不喜欢框架自带的日志配置方式 在此,推荐使用一种自定义文件目录与log记录形式的方案 希望有此需求的道友,能…

IDEA下方工具栏SideBar没有Services解决方法 IDEA配合微服务学习多端口管理打开Services栏方法

问题 微服务学习时,一次要打开多个端口,比如8080给order模块、8081给user模块……这就需要用idea管理多端口。 这时候就可以用到Services栏进行管理。 解决 首先看下方Sidebar没有Services。 打开Services 打开方式一:手动打开 在IDEA中…

智能语音开放平台选哪家,启英泰伦提供硬件、软件一体化服务

离线智能语音产品方案的开发主要包含两个方面:硬件和软件。这里硬件是指采用语音芯片等电子元器件为该产品设计的电路板,软件是指基于电路板上主控芯片的种类及产品功能需求所开发的代码,再经过编译工具等生成可下载到主控芯片中的语音固件&a…

【云原生、k8s】Calico网络策略

第四阶段 时 间:2023年8月17日 参加人:全班人员 内 容: Calico网络策略 目录 一、前提配置 二、Calico网络策略基础 1、创建服务 2、启用网络隔离 3、测试网络隔离 4、允许通过网络策略进行访问 三、Calico网络策略进阶 1、创…