為什么 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.pswp.cn/bicheng/75121.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/75121.shtml
英文地址,請注明出處:http://en.pswp.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 …