成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

ThreadLocal 你怎么動不動就內存泄漏?

存儲 存儲軟件
ThreadLocal 解決了什么問題呢?它是為了解決對象不能被多線程共享訪問的問題,通過 threadLocal.set() 方法將對象實例保存在每個線程自己所擁有的 threadLocalMap 中,這樣的話每個線程都使用自己的對象實例,彼此不會影響從而達到了隔離的作用,這樣就解決了對象在被共享訪問時帶來的線程安全問題。

[[341471]]

本文轉載自微信公眾號「Java極客技術」,作者鴨血粉絲。轉載本文請聯系Java極客技術公眾號。  

如果說 ThreadLocal 的話,那肯定就會涉及到內存泄漏,為啥嘞

因為 吧啦吧啦 ~

ThreadLocal 解決了什么問題呢?

它是為了解決對象不能被多線程共享訪問的問題,通過 threadLocal.set() 方法將對象實例保存在每個線程自己所擁有的 threadLocalMap 中,這樣的話每個線程都使用自己的對象實例,彼此不會影響從而達到了隔離的作用,這樣就解決了對象在被共享訪問時帶來的線程安全問題。

啥意思呢?打個比方,現在公司所有人都要填寫一個表格,但是只有一支筆,這個時候就只能上個人用完了之后,下個人才可以使用,為了保證"筆"這個資源的可用性,只需要保證在接下來每個人的獲取順序就可以了,這就是 lock 的作用,當這支筆被別人用的時候,我就加 lock ,你來了那就進入隊列排隊等待獲取資源(非公平方式那就另外說了),這支筆用完之后就釋放 lock ,然后按照順序給下個人使用。

但是完全可以一個人一支筆對不對,這樣的話,你填寫你的表格,我填寫我的表格,咱倆誰都不耽擱誰。這就是 ThreadLocal 在做的事情,因為每個 Thread 都有一個副本,就不存在資源競爭,所以也就不需要加鎖,這不就是拿空間去換了時間嘛!

在開始之前,咱們先把 Thread, ThreadLocal, ThreadLocalMap 的關系捋一捋:

 

可以看到,在 Thread 中持有一個 ThreadLocalMap , ThreadLocalMap 又是由 Entry 來組成的,在 Entry 里面有 ThreadLocal 和 value

ThreadLocal 為啥動不動就內存泄漏呢?

在這里先給個解釋,后面咱們再詳細分析:

首先是因為 ThreadLocal 是基于 ThreadLocalMap 實現的,其中 ThreadLocalMap 的 Entry 繼承了 WeakReference ,而 Entry 對象中的 key 使用了 WeakReference 封裝,也就是說, Entry 中的 key 是一個弱引用類型,對于弱引用來說,它只能存活到下次 GC 之前

如果此時一個線程調用了 ThreadLocalMap 的 set 設置變量,當前的 ThreadLocalMap 就會新增一條記錄,但由于發生了一次垃圾回收,這樣就會造成一個結果: key 值被回收掉了,但是 value 值還在內存中,而且如果線程一直存在的話,那么它的 value 值就會一直存在

這樣被垃圾回收掉的 key 就會一直存在一條引用鏈: Thread -> ThreadLocalMap -> Entry -> Value :

 

就是因為這條引用鏈的存在,就會導致如果 Thread 還在運行,那么 Entry 不會被回收,進而 value 也不會被回收掉,但是 Entry 里面的 key 值已經被回收掉了

這只是一個線程,如果再來一個線程,又來一個線程…多了之后就會造成內存泄漏

知道是怎么造成內存泄漏之后,接下來要做的事情就好說了,不是因為 value 值沒有被回收掉所以才會導致內存泄露的嘛

那使用完 key 值之后,將 value 值通過 remove 方法 remove 掉,這樣的話內存中就不會有 value 值了,也就防止了內存泄漏嘛

ThreadLocal 是基于 ThreadLocalMap 實現的?

OK ,上面的內容講完了,接下來一一來看

首先,你怎么知道 ThreadLocal 是基于 ThreadLocalMap 實現的呢?

從源碼知道的~

在源碼中能夠看到下面這幾行代碼:

  1. public class ThreadLocal<T> { 
  2.     static class ThreadLocalMap { 
  3.         static class Entry extends WeakReference<ThreadLocal<?>> { 
  4.             /** The value associated with this ThreadLocal. */ 
  5.             Object value; 
  6.  
  7.             Entry(ThreadLocal<?> k, Object v) { 
  8.                 super(k); 
  9.                 value = v; 
  10.             } 
  11.         } 
  12.     } 

代碼中說的很清楚了,在 ThreadLocal 內部維護著 ThreadLocalMap ,而它的 Entry 則繼承自 WeakReference 的 ThreadLocal ,其中 Entry 的 k 為 ThreadLocal , v 為 Object ,在調用 super(k) 時就將 ThreadLocal 實例包裝成了一個 WeakReference

強弱引用這塊內容阿粉就直接放一個表格吧:

引用類型 功能特點
強引用 ( Strong Reference ) 被強引用關聯的對象永遠不會被垃圾回收器回收掉
軟引用( Soft Reference ) 軟引用關聯的對象,只有當系統將要發生內存溢出時,才會去回收軟引用引用的對象
弱引用 ( Weak Reference ) 只被弱引用關聯的對象,只要發生垃圾收集事件,就會被回收
虛引用 ( Phantom Reference ) 被虛引用關聯的對象的唯一作用是能在這個對象被回收器回收時收到一個系統通知

從表格中應該能夠看出來,弱引用的對象只要發生垃圾收集事件,就會被回收

所以弱引用的存活時間也就是下次 GC 之前了

在這里阿粉就有個問題想問問了:為什么 ThreadLocal 采用弱引用,而不是強引用嘞?

在 ThreadLocalMap 上面有些注釋,我在這里摘錄一部分,或許可以從中窺探一二:

To help deal with very large and long-lived usages, the hash table entries use WeakReferences for keys

翻譯一下就是:(雖然我英語不是很好

為了解決非常大且長期使用的問題,哈希表使用了弱引用的 key

假設,假設, ThreadLocal 使用的是強引用,會怎樣呢?

如果是強引用的話,在表格中也能夠看出來,被強引用關聯的對象,永遠都不會被垃圾回收器回收掉

如果引用的 ThreadLocal 對象被回收了,但是 ThreadLocalMap 還持有對 ThreadLocal 的強引用,如果沒有 remove 的話, 在 GC 時進行可達性分析, ThreadLocal 依然可達,這樣就不會對 ThreadLocal 進行回收,但是我們期望的是引用的 ThreadLocal 對象被回收,這樣不就達不到目的了嘛

使用弱引用的話,雖然會出現內存泄漏的問題,但是在 ThreadLocal 生命周期里面,都有對 key 值為 null 時進行回收的處理操作

所以,使用弱引用的話,可以在 ThreadLocal 生命周期中盡可能保證不出現內存泄漏的問題

 

啥?在 ThreadLcoal 生命周期里面,都有對 key 值為 null 時進行回收的處理操作?有證據么?

 

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2021-02-18 16:53:44

內存ThreadLocal線程

2020-09-11 07:38:50

內存泄漏檢測

2020-11-09 06:00:04

Windows 10Windows操作系統

2021-08-10 09:58:59

ThreadLocal內存泄漏

2018-10-25 15:24:10

ThreadLocal內存泄漏Java

2022-05-09 14:09:23

多線程線程安全

2025-04-01 05:22:00

JavaThread變量

2024-03-22 13:31:00

線程策略線程池

2024-09-29 08:57:25

2022-11-04 08:47:52

底層算法數據

2024-02-02 09:00:14

內存泄漏對象

2018-05-08 15:42:30

PC升級筆記本

2024-03-11 08:22:40

Java內存泄漏

2023-12-18 10:45:23

內存泄漏計算機服務器

2025-03-28 08:53:51

2012-02-22 21:28:58

內存泄漏

2015-03-30 11:18:50

內存管理Android

2022-08-26 07:33:49

內存JVMEntry

2017-10-22 15:34:34

手機內存清理內存手機

2023-11-28 12:25:02

多線程安全
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品小短片 | 在线免费观看黄视频 | 免费看91| 欧美国产中文 | 久久国产精品一区二区 | 久久久久久国产一区二区三区 | 黄色毛片在线观看 | 一区二区在线观看免费视频 | 自拍偷拍亚洲视频 | 高清久久久 | 日韩视频在线观看一区二区 | 99久久夜色精品国产亚洲96 | 欧美精品在线看 | 国产乱码久久久久久 | 日韩国产一区二区三区 | 国产一区二区在线播放 | 日韩欧美中文在线 | 日韩国产一区二区三区 | 国产成人精品一区二 | 精品国产区 | 性天堂网 | 96av麻豆蜜桃一区二区 | 国产亚洲一区在线 | 成人精品区 | 欧美在线视频一区 | 男女羞羞视频在线 | 成人av电影在线 | 国产日韩精品一区 | 国产精品自产拍 | 免费看a| 国产精品乱码一区二三区小蝌蚪 | 久久精品91久久久久久再现 | 免费黄色片视频 | 国产精品一区二区不卡 | 精品综合| 日韩久久综合网 | 午夜网 | 日韩在线欧美 | 精品国产91乱码一区二区三区 | 亚洲巨乳自拍在线视频 | 亚洲福利av |