Java并发面试题:(七)ThreadLocal原理和内存泄漏

在这里插入图片描述

ThreadLocal是什么?

ThreadLocal是线程本地存储机制,可以将数据缓存在线程内部。ThreadLocal存储的变量在线程内共享的,在线程间又是隔离的。

ThreadLocal实现原理?

ThreadLocal的底层是ThreadLocalMap,每个Thread都有一个ThreadLocalMap。
ThreadLocalMap存储的键值对,key就是ThreadLocal实例,value就是要缓存的值。
当创建ThreadLocal,set数据时调用的是ThreadLocalMap的set方法,set方法将ThreadLocal对象和缓存值存入Map。也就是说,想要存入的ThreadLocal中的数据实际上并没有存到ThreadLocal对象中去,而是以这个ThreadLocal实例作为key存到了当前线程中的ThreadLocalMap中去了,获取ThreadLocal的值时同样也是这个道理。这也就是为什么ThreadLocal可以实现线程之间隔离的原因了。

ThreadLocal的为什么会内存泄露

在每一个线程Thread对象中,都维护了一个ThreadLocalMap对象。ThreadLocalMap中又维护了一个k v 形式的Entry对象,key指向了当前ThreadLocal对象,value就是我们实际在ThreadLocal中存储的值。Entry中的key存放是ThreadLocal的弱引用。
因为ThreadLocalMap的key对它的引用是弱引用,将会在下一次gc被回收,那就会出现key变成null,如果这时value外部也没有强引用指向它,那么value就永远也访问不到了,按理也应该被GC回收,但是由于ThreadLocalMap.Entry对象还在强引用value,导致value无法被回收,这时「内存泄漏」就发生了,value成了一个永远也无法被访问,但是又无法被回收的对象。

为什么使用弱引用

假设key也用强引用指向当前ThreadLocal的话,那么如果我这时候写 t1 = null ,按理说下次GC时,应该要把堆内存的new ThreadLocal() 这个对象进行回收才对,但此时我的key如果设计成强引用,显然GC无法对它进行回收,因为key还强引用指向它。这就会造成内存泄漏,所以ThreadLocal存值时,key采用弱引用。key使用弱引用的特点就很明显了(只要是GC回收,不管内存够不够,都会回收弱引用指向的对象),当我写 t1 = null , 下次GC回收时,就可以将new ThreadLocal() 这个对象会被回收掉。

在 ThreadLocalMap 中的set/getEntry 方法中,会对 key 为 null(也即是 ThreadLocal 为 null )进行判断,如果为 null 的话,那么会把 value 置为 null 的.这就意味着使用完 ThreadLocal , CurrentThread 依然运行的前提下.就算忘记调用 remove 方法,弱引用比强引用可以多一层保障:弱引用的 ThreadLocal 会被回收.对应value在下一次 ThreadLocaIMap 调用 set/get/remove 中的任一方法的时候会被清除,从而避免内存泄漏.

避免内存泄漏

  • 将ThreadLocal设置为空之前,执行remove()方法,会将key为空的键值对清空 尽量将
  • ThreadLocal设置成static
  • 非必要尽量不要在ThreadLocal中放大对象

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

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

相关文章

Open3D(C++) 最小二乘拟合平面(拉格朗日乘子法)

目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。 一、算法原理 设拟合出的平面方程为: a x + b y + c

SpringCloud:自定义skywalking链路追踪

一、添加依赖&#xff1a; <dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId><version>8.7.0</version></dependency><dependency><groupId>org.apache.sk…

Mac Intellij Idea get/set方法快捷键

Control Retrun(回车键) Command n 参考&#xff1a; Mac Intellij Idea get/set方法快捷键-CSDN博客

Cornerstone for Mac:高效SVN管理的黄金标准

在当今的软件开发领域&#xff0c;版本控制系统是不可或缺的一部分。其中&#xff0c;Subversion&#xff08;SVN&#xff09;是一个广泛使用的版本控制系统&#xff0c;有助于团队协同工作&#xff0c;实现代码的版本管理和追踪。对于Mac用户来说&#xff0c;Cornerstone是一款…

【Linux】进程概念与进程状态

文章目录 一、进程概念1.进程的概念2.进程的描述-PCB 二、进程相关的基本操作1.组织进程2.查看进程3.结束进程4.通过系统调用获取进程标示符5.通过系统调用创建进程-fork初识 三、进程状态1.普遍操作系统层面的进程状态2.Linux操作系统的进程状态 四、两种特殊的进程状态1.僵尸…

C++ 01.学习C++的意义-狄泰软件学院

一些历史 UNIX操作系统诞生之初是用汇编语言编写的随着UNIX系统的发展&#xff0c;汇编语言的开发效率成为瓶颈&#xff0c;所以需要一个新的语言替代汇编语言1971年通过对B语言改良&#xff0c;使其能直接产生机器代码&#xff0c;C语言诞生UNIX使用C语言重写&#xff0c;同时…

Excel文件带有密码的只读模式,如何设置?

Excel带有密码的除了打开密码和工作表保护以外&#xff0c;其实还有一种可以设置密码的方法&#xff0c;今天给大家分享如何设置带有密码的只读模式。 打开excel文件&#xff0c;将文件进行【另存为】设置&#xff0c;然后停留在保存路径的界面中&#xff0c;我们点击下面的工…

《java 桌面软件开发》swing 以鼠标为中心放大缩小移动图片

swing 使用Graphic2D 绘制图片&#xff0c;要实现对图片进行缩放和自由拖动。 1.以鼠标所在的位置为中心&#xff0c;滚轮控制缩放 2.缩放后再支持鼠标拖动。 基本原理&#xff1a; 利用scale() 函数。进行缩放。但是要注意的地方是&#xff0c;如果是在 public void paintCom…

未来装备探索:数字孪生装备

源自&#xff1a;《计算机集成制造系统》 作者&#xff1a;陶飞 张辰源 张贺 程江峰 邹孝付 徐慧 王勇 谢兵兵 “人工智能技术与咨询” 发布 摘 要 工程装备、制造装备、医疗装备等各类装备是加快国家基础建设&#xff0c;提升国家经济实力和保障医疗健康的重要…

2023年【电工(高级)】报名考试及电工(高级)模拟考试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年【电工&#xff08;高级&#xff09;】报名考试及电工&#xff08;高级&#xff09;模拟考试题&#xff0c;包含电工&#xff08;高级&#xff09;报名考试答案和解析及电工&#xff08;高级&#xff09;模拟考…

JAVA基础(JAVA SE)学习笔记(六)面向对象编程(基础)

前言 1. 学习视频&#xff1a; 尚硅谷Java零基础全套视频教程(宋红康2023版&#xff0c;java入门自学必备)_哔哩哔哩_bilibili 2023最新Java学习路线 - 哔哩哔哩 第二阶段&#xff1a;Java面向对象编程 6.面向对象编程&#xff08;基础&#xff09; 7.面向对象编程&…

基于水基湍流优化的BP神经网络(分类应用) - 附代码

基于水基湍流优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于水基湍流优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.水基湍流优化BP神经网络3.1 BP神经网络参数设置3.2 水基湍流算法应用 4.测试结果…

【OpenCV实现鼠标绘图,轨迹栏做调色板,图像的基本操作】

文章目录 鼠标绘图轨迹栏做调色板图像的基本操作 鼠标绘图 在OpenCV中操作鼠标事件 函数&#xff1a;cv.setMouseCallback() 目的是在鼠标双击的地方画一个圆。首先&#xff0c;我们需要创建一个鼠标回调函数&#xff0c;该函数会在鼠标事件发生时执行。鼠标事件包括左键按下…

C++QT---QT-day3

#include "widget.h" #include "ui_widget.h" //需要在.pro文件第一行加 texttospeechWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);ui->lineEdit->setPlaceholderText("时:分:秒");//设…

移动端1px-从基本原理到开源解决方案介绍

1px 不够准确&#xff0c;应该说成 1 物理像素 为什么有 1px 这个问题&#xff1f;实现 1px 有哪些方法&#xff1f;这些方法分别有哪些优缺点&#xff1f;开源项目中使用的哪些解决方案&#xff1f;如何在项目中处理 1px 的相关问题&#xff1f; 基本概念 首先&#xff0c;我们…

Nginx Proxy代理

代理原理 反向代理产生的背景&#xff1a; 在计算机世界里&#xff0c;由于单个服务器的处理客户端&#xff08;用户&#xff09;请求能力有一个极限&#xff0c;当用户的接入请求蜂拥而入时&#xff0c;会造成服务器忙不过来的局面&#xff0c;可以使用多个服务器来共同分担成…

k8s集群授权prometheus(集群外部署)

一、前言 在集群外部prometheus想要调用k8s集群的apiserver获取监控数据需要通过token和ca验证&#xff0c;在集群内部部署的prometheus就不会有这个情况&#xff0c;因为集群内部部署prometheus pod的时候就已经注入了访问集群的token和ca文件&#xff0c;所以以下就针对k8s集…

什么是模拟芯片,模拟芯片都有哪些测试指标?

模拟芯片又称处理模拟信号的集成电路 模拟集成电路主要是指由电容、电阻、晶体管等组成的模拟电路集成在一起用来处理模拟信号的集成电路。有许多的模拟集成电路&#xff0c;如运算放大器、模拟乘法器、锁相环、电源管理芯片等。 模拟集成电路的主要构成电路有&#xff1a;放…

【jvm】虚拟机栈之局部变量表

目录 一、说明二、代码分析2.1 代码示例2.2 执行javap2.3 jclasslib插件查看 三、对slot的理解3.1 说明3.2 slot索引图3.3 实例方法的局部变量表3.4 long和double类型变量占2个slot 四、slot的重复利用4.1 说明4.2 变量c复用变量b的槽位 五、静态变量与局部变量对比 一、说明 1…

AQS中lock源码解析

什么是AQS&#xff1f; 就是基于双向链表CAS实现的锁的一种机制或者方法思想。就是AbstractQueuedSynchronizer&#xff0c;是Java并发包下的一个基类基于AQS实现的同步器包括&#xff1a;ReentrantLock、CountDownLatch、Samaphone、FutureTask、ReentrantWriteLock Abstrac…