为什么 ThreadLocalMap 的 key 是弱引用 value是强引用

问题一:为什么 ThreadLocalMap 的 key 是弱引用?

【假设 Entry 的 key 是对 ThreadLocal 对象的强引用】:这个 Entry 又持有 ThreadLocal 对象和 value 对象的强引用。如果在其他地方都没有对这个 ThreadLocla 对象的引用了、然后在使用 ThreadLocalMap 的过程中又没有正确地在用完后就调用 remove 方法、所以这个 ThreadLocal 对象和所关联的 value 对象就会跟随着线程一直存在、这样就会可能会造成内存泄漏问题。

特别是在使用线程池的时候、核心线程是会一直存在直到程序结束、如果这些线程中的 ThreadLocalMap 中的数据没有被及时清理、就会一直占用内存、而且在线程复用时可能会导致数据错乱的危险。

【Entry 的 key 是对 ThreadLocal 对象的弱引用】:弱引用就意味着、如果没有其他引用对象的强引用关系、那么这个仅被弱引用引用着的对象在下次 GC 时就会被回收掉、这样在一定程度上降低内存泄漏的风险。但同时也引入了新的问题、key 虽然被回收了、但是 value 对象还在、我们无法获取、也无法删除、这样也会存在内存泄漏的风险。

虽然 ThreadLocalMap 中在进行 set 和 get 操作时会进行启发式清理和探测式清理、清理一部分 key 为 null 的 Entry 对象、但是这也只是一种后备选择方案

最重要的还是开发人员在编写代码时记得在使用完数据后及时调用 remove() 方法手动清理

补充:

【内存泄漏就是:有些对象已经不再使用了、但是由于没有正确处理对象的引用关系、使得这个无用的对象还一直被 GC Root 直接或间接引用着、垃圾回收时就无法清理掉这些对象、如果这类对象存在很多、就会导致内存泄漏。简单地说就是有些无用对象占用着宝贵的内存空间、但又没办法清理掉它们 可达性分析是现代垃圾回收器用来判断对象是否存活的核心算法】

问题二:为什么 ThreadLocalMap 的 value 是强引用?

【假设Entry 的 value 是弱引用】:假设 key 所引用的 ThreadLocal 对象还被其他的引用对象强引用着,那么这个 ThreadLocal 对象就不会被 GC 回收、但如果 value 是弱引用且不被其他引用对象引用着、那 GC 的时候就被回收掉了、那线程通过 ThreadLocal 来获取 value 的时候就会获得 null,显然这不是我们希望的结果。因为对我们来说、value 才是我们想要保存的数据、ThreadLcoal 只是用来关联 value 的、如果 value 都没了、还要 ThreadLocal 干啥呢

面试参考回答:

面试官您好关于 ThreadLocalMap 的 key 使用弱引用、value 使用强引用的问题

我的理解是这样的:

首先要理解这样设计的目的是为了尽可能地避免内存泄漏。

  • Key 使用弱引用 假设 key 是强引用、那么即使 ThreadLocal 对象本身已经没有其他地方引用了、由于 ThreadLocalMap 中 Entry 的强引用、这个 ThreadLocal 对象仍然无法被垃圾回收。如果线程一直存活(比如线程池中的线程)、这个 ThreadLocal 对象和对应的 value 就会一直占用内存、造成内存泄漏。使用弱引用、当 ThreadLocal 对象没有外部强引用时、在下次 GC 的时候、key 就会被回收、降低了内存泄漏的风险。

  • Value 使用强引用: Value 是我们真正想要存储的数据,如果 value 也使用弱引用、那么在 ThreadLocal 对象还存活的情况下、value 却可能因为没有强引用而被 GC 回收、导致我们通过 ThreadLocal 获取到的 value 为空、这显然是不符合 ThreadLocal 的设计目的的。ThreadLocal 的作用就是关联数据、如果数据都没了ThreadLocal 就失去了意义。

而且虽然 key 使用弱引用可以降低内存泄漏的风险、但仍然存在 value 无法回收的问题。

当 key 被回收后value 仍然被 Entry 强引用。如果线程一直存活、这个 value 就会一直占用内存。

因此ThreadLocalMap 在 set()get() 操作时会进行启发式清理、移除 key 为 null 的 Entry 但这只是一个补救措施。

最根本的解决办法还是需要开发者在使用完 ThreadLocal 后、手动调用 remove() 方法、及时清理 ThreadLocalMap 中的 Entry,避免内存泄漏。

总结: 弱引用 key 降低了 ThreadLocal 对象本身的内存泄漏风险、强引用 value 保证了数据的可用性。

但最终避免内存泄漏、需要开发者养成良好的习惯、及时清理 ThreadLocal。

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

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

相关文章

DeepSeek本地部署(linux)

一、下载并安装Ollama 1.下载Ollama Ollama官网:Ollama 点击"Download",会跳转至下载页面。 1.1在线下载安装 可复制此命令到Linux服务器进行在线下载,如下载速度过慢,可选择离线下载安装。 curl -fsSL https://ollama.com/install.sh | sh1.2离线下载安装 …

基于Halcon仿VM流程列表的执行效果

Halcon本身应用需要一定的门槛,但是也可以封装成类似VM简单易操作的样子 上期文章分享的是连线功能,本期分享数据传参 1,定义通用属性和方法 public class BaseModel {public HObject HInput { get; set; }//图像输入public HObject HOutpu…

打车APP订单系统逻辑梳理与实现

一、逻辑分析 打车 APP 订单系统是整个打车业务的核心,负责处理从乘客下单到行程结束的一系列流程,涉及乘客、司机和平台三方的交互。 乘客端 下单:乘客打开 APP,输入上车地点、目的地,选择车型等信息后提交订单。此时…

杂草YOLO系列数据集4000张

一份开源数据集——杂草YOLO数据集,该数据集适用于农业智能化、植物识别等计算机视觉应用场景。 数据集详情 ​训练集:3,664张高清标注图像​测试集:180张多样性场景样本​验证集:359张严格筛选数据 下载链接 杂草YOLO数据集分…

算法 | 河马优化算法原理,公式,应用,算法改进及研究综述,matlab代码

以下是关于河马优化算法(Hippopotamus Optimization Algorithm, HO)的完整综述,包含原理、公式、应用场景、改进方向及可直接运行的 Matlab 完整代码。一、算法原理 河马优化算法(HO)由Amiri等人于2024年提出,是受河马群体行为启发的元启发式算法,其核心基于以下三阶段行…

知识就是力量——HELLO GAME WORD!

你好!游戏世界! 简介环境配置前期准备好文章介绍创建头像小功能组件安装本地中文字库HSV颜色空间音频生成空白的音频 游戏UI开发加载动画注册登录界面UI界面第一版第二版 第一个游戏(贪吃蛇)第二个游戏(俄罗斯方块&…

Android Activity 的 launchMode 与 Task Stack 管理

Android 中的 android:launchMode 决定了 Activity 在启动时如何在任务栏中管理它的存在方式。下面我们来结合 Task Stack 管理详细解释。 1. android:launchMode 的四种模式 1.1 standard (标准模式, 默认) 启动方式:每次启动都会创建一个新实例并压入栏任务堆中…

2025选择手机之我见

自从开店之后,没当有手机召开发布会,我就得去大概看看,了解一下屏幕,充电之类的东西。毕竟跟我的生意息息相关,而且还得研究要不要上新,从我目前卖货的情况来看,折叠屏不是大众的选择&#xff0…

【区块链安全 | 第九篇】基于Heimdall设计的智能合约反编译项目

文章目录 背景目的安装1、安装 Rust2、克隆 heimdall-dec3、编译 heimdall-dec4、运行 heimdall-dec 使用说明1、访问 Web 界面2、输入合约信息3、查看反编译结果 实战演示1、解析普通合约2、解析代理合约 背景 在区块链安全研究中,智能合约的审计和分析至关重要。…

利用 PCI-Express 交换机实现面向未来的推理服务器

在数据中心系统的历史上,没有比被 Nvidia 选为其 AI 系统的组件供应商更高的赞誉了。 这就是为什么新兴的互连芯片制造商 Astera Labs 感到十分高兴,因为该公司正在 PCI-Express 交换机、PCI-Express 重定时器和 CXL 内存控制器方面与 Broadcom 和 Marv…

智能交通预警杆:守护道路安全的科技先锋

在城市化进程加速以及机动车保有量持续增长的背景下,道路交通安全与拥堵问题渐趋严峻。智能交通预警杆应时而生,其集成多种高科技功能,正逐步成为现代城市交通管理中至关重要的智能装备,对于提升交通效率、保障出行安全发挥着关键…

flink 基站与服务器长连接,每次连接和断开都会上报数据,统计过去一小时每个基站断开次数和时长

模拟生成数据 CREATE TABLE ods_station_log (base_station_id int, -- 基站IDevent_type int, -- 事件类型: connect/disconnectevent_time TIMESTAMP_LTZ(3), -- 事件时间WATERMARK FOR event_time AS event_time - INTERVAL 5 SECOND -- 允许5秒乱序 ) WITH …

自定义一些C语言的字符串函数

一、代码如下 (一)十六进制字符串转十进制整数 #include<stdio.h> // 把一个十六进制字符转成十进制整数 int hexToInt(char hexs[]){ int index; int k 0; for(k 0; ; k) { if(hexs[k] \0) { index k; break; …

核函数(机器学习深度学习)

一、核函数的基本概念 核函数&#xff08;Kernel Function&#xff09; 是机器学习中处理非线性问题的核心工具&#xff0c;通过隐式映射将数据从原始空间转换到高维特征空间&#xff0c;从而在高维空间中实现线性可分或线性建模。其数学本质是计算两个样本在高维空间中的内积…

微服务架构中的精妙设计:服务注册/服务发现-Eureka

一.使用注册中心背景 1.1服务远程调用问题 服务之间远程调⽤时, 我们的URL是写死的 String url "http://127.0.0.1:9090/product/" orderInfo.getProductId(); 缺点&#xff1a; 当更换机器, 或者新增机器时, 这个URL就需要跟着变更, 就需要去通知所有的相关服…

极速版:栈的内存/局部变量表/堆的内存细分

1. 栈的存储 每个线程都有自己的栈&#xff0c;栈中数据以栈帧&#xff08;Stack Frame&#xff09;为基本单位 线程上正在执行的每个方法都各自对应一个栈桢&#xff08;Stack Frame&#xff09; 栈桢是一个内存区块&#xff0c;是一个数据集&#xff0c;维系着方法执行过程…

【操作系统】内存泄漏 vs 内存碎片

【操作系统】内存泄漏 vs 内存碎片 内存泄漏&#xff08;Memory Leak&#xff09; vs 内存碎片&#xff08;Memory Fragmentation&#xff09;1. 内存泄漏&#xff08;Memory Leak&#xff09;2. 内存碎片&#xff08;Memory Fragmentation&#xff09;3. 内存泄漏 vs 内存碎片…

力扣HOT100之矩阵:73. 矩阵置零

这道题我没有想到什么好的办法&#xff0c;直接暴力AC了&#xff0c;直接遍历两次矩阵&#xff0c;第一次遍历用两个向量分别记录出现0的行数和列数&#xff0c;第二次遍历就判断当前的元素的行数或者列数是否出现在之前的两个向量中&#xff0c;若出现了就直接置零&#xff0c…

​Flink/Kafka在python中的用处

一、基础概念 1. ​Apache Kafka 是什么&#xff1f; ​核心功能&#xff1a;Kafka 是一个分布式流处理平台&#xff0c;主要用于构建实时数据管道和流式应用程序。​核心概念&#xff1a; ​生产者&#xff08;Producer&#xff09;​&#xff1a;向 Kafka 发送数据的程序。…

推荐系统(十八):优势特征蒸馏(Privileged Features Distillation)在商品推荐中的应用

在商品推荐系统中&#xff0c;粗排和精排环节的知识蒸馏方法主要通过复杂模型&#xff08;Teacher&#xff09;指导简单模型&#xff08;Student&#xff09;的训练&#xff0c;以提升粗排效果及与精排的一致性。本文将以淘宝的一篇论文《Privileged Features Distillation at …