国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

為什么ThreadLocal容易導致內存泄漏?

開發 前端
我們通常創建的變量可以被任何線程訪問和修改,而是用ThreadLocal創建的變量只能通過當前線程去訪問和修改。

[[416507]]

本文轉載自微信公眾號「三不猴子」,作者sanbuhouzi。轉載本文請聯系三不猴子公眾號。

為什么ThreadLocal容易導致內存泄漏?

ThreadLocal是什么?

官方解釋為:

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable.

我們通常創建的變量可以被任何線程訪問和修改,而是用ThreadLocal創建的變量只能通過當前線程去訪問和修改。

ThreadLocal原理

jdk版本1.8,我們先看一下ThreadLocal的源碼,先從set方法開始。

  1. /** 
  2.    * Sets the current thread's copy of this thread-local variable 
  3.    * to the specified value.  Most subclasses will have no need to 
  4.    * override this method, relying solely on the {@link #initialValue} 
  5.    * method to set the values of thread-locals. 
  6.    * 
  7.    * @param value the value to be stored in the current thread's copy of 
  8.    *        this thread-local
  9.    */ 
  10.   public void set(T value) { 
  11.       Thread t = Thread.currentThread(); 
  12.       ThreadLocalMap map = getMap(t); 
  13.       if (map != null
  14.           map.set(this, value); 
  15.       else 
  16.           createMap(t, value); 
  17.   } 

這個ThreadLocalMap是ThreadLocal的一個內部類,key是當前Thread對象,value是我們要存的對象。首先拿到當前線程對象,然后獲取了個map,然后往這個map中放了當前ThreadLocal對象,如果map為空則創建一個map。看看getMap的邏輯。

  1. /** 
  2.     * Get the map associated with a ThreadLocal. Overridden in 
  3.     * InheritableThreadLocal. 
  4.     * 
  5.     * @param  t the current thread 
  6.     * @return the map 
  7.     */ 
  8.    ThreadLocalMap getMap(Thread t) { 
  9.        return t.threadLocals; 
  10.    } 

getMap就是在Thread成員變量中獲取一個map。往下就是ThreadLocalMap.set()看看set的邏輯。

  1. /** 
  2.      * Set the value associated with key
  3.      * 
  4.      * @param key the thread local object 
  5.      * @param value the value to be set 
  6.      */ 
  7.     private void set(ThreadLocal<?> key, Object value) { 
  8.  
  9.         // We don't use a fast path as with get() because it is at 
  10.         // least as common to use set() to create new entries as 
  11.         // it is to replace existing ones, in which case, a fast 
  12.         // path would fail more often than not
  13.  
  14.         Entry[] tab = table
  15.         int len = tab.length; 
  16.         int i = key.threadLocalHashCode & (len-1); 
  17.  
  18.         for (Entry e = tab[i]; 
  19.              e != null
  20.              e = tab[i = nextIndex(i, len)]) { 
  21.             ThreadLocal<?> k = e.get(); 
  22.  
  23.             if (k == key) { 
  24.                 e.value = value; 
  25.                 return
  26.             } 
  27.  
  28.             if (k == null) { 
  29.                 replaceStaleEntry(key, value, i); 
  30.                 return
  31.             } 
  32.         } 
  33.  
  34.         tab[i] = new Entry(key, value); 
  35.         int sz = ++size
  36.         if (!cleanSomeSlots(i, sz) && sz >= threshold) 
  37.             rehash(); 
  38.     } 

這里構造了個Entry對象,這個Entry可以看成是map的一行數據,一個key-value對。再看看Entry的源碼。

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

這個Entry對象竟然是繼承了WeakReference對象。上面的流程用圖畫出來就是這樣的。

總結起來就是:

  • 每個Thread維護著一個ThreadLocalMap的引用
  • ThreadLocalMap是ThreadLocal的內部類,用Entry來進行存儲
  • 調用ThreadLocal的set()方法時,實際上就是往ThreadLocalMap設置值,key是ThreadLocal對象,value是傳遞進來的對象
  • 調用ThreadLocal的get()方法時,實際上就是往ThreadLocalMap獲取值,key是ThreadLocal對象

ThreadLocal本身并不存儲值,它只是作為一個key來讓線程從ThreadLocalMap獲取value。

什么是弱引用呢? 為什么ThreadLocal要使用弱引用呢?

官方文檔解釋為:

  1. /** 
  2.  * Weak reference objects, which do not prevent their referents from being 
  3.  * made finalizable, finalized, and then reclaimed.  Weak references are most 
  4.  * often used to implement canonicalizing mappings. 
  5.  * 
  6.  * <p> Suppose that the garbage collector determines at a certain point in time 
  7.  * that an object is <a href="package-summary.html#reachability">weakly 
  8.  * reachable</a>.  At that time it will atomically clear all weak references to 
  9.  * that object and all weak references to any other weakly-reachable objects 
  10.  * from which that object is reachable through a chain of strong and soft 
  11.  * references.  At the same time it will declare all of the formerly 
  12.  * weakly-reachable objects to be finalizable.  At the same time or at some 
  13.  * later time it will enqueue those newly-cleared weak references that are 
  14.  * registered with reference queues. 
  15.  * 
  16.  * @author   Mark Reinhold 
  17.  * @since    1.2 
  18.  */ 

就是不會被程序計數器計數的引用,所以在垃圾回收器回收的時候不管是否有引用都會被回收。由于垃圾回收器是一個優先級很低的線程,因此不一定會很快發現那些只具有弱引用的對象。

ThreadLocal為什么要使用弱引用?

因為當我們存入的對象被置為null的時候,也就是ThreadLocalMap的value為null,ThreadLocalMap的key是弱引用此時在下一次垃圾回收器回收垃圾的時候就可以回收掉這個key-value也是就一個Entry對象了。

既然弱引用是有助于垃圾回收的,那為什么ThreadLocal還是容易導致內存泄漏?

弱引用確實是有助于垃圾回收,但是也是有弊端的,假設我們現在存入了一個對象,此時虛擬機gc,將key弱引用回收,但是value依然是強引用,key被回收了,這個value無法通過通過ThreadLocal對象的get方法獲取,它永遠不會被訪問到了,所以存在內存泄漏的風險。

如何避免內存泄漏

  • 在ThreadLocal使用前后都調用remove清理,同時對異常情況也要在finally中清理。 
  • 盡量不要使用全局的ThreadLocal,靜態變量的生命周期和類的生命周期是一致的,而類的卸載時機可以說比較苛刻,這會導致靜態ThreadLocal無法被垃圾回收,容易出現內存泄漏。

 

責任編輯:武曉燕 來源: 三不猴子
相關推薦

2025-04-01 05:22:00

JavaThread變量

2024-09-29 08:57:25

2022-05-09 14:09:23

多線程線程安全

2018-10-25 15:24:10

ThreadLocal內存泄漏Java

2022-10-18 08:38:16

內存泄漏線程

2020-09-10 07:40:28

ThreadLocal內存

2011-05-24 16:39:09

Cfree()

2024-03-22 13:31:00

線程策略線程池

2021-02-18 16:53:44

內存ThreadLocal線程

2022-07-26 07:14:20

線程隔離Thread

2025-07-28 02:11:00

2017-02-27 15:43:51

2023-05-29 07:17:48

內存溢出場景

2019-12-17 10:01:40

開發技能代碼

2017-06-02 10:57:29

Android內存泄漏Dialog

2023-10-24 09:30:49

Java內存

2024-11-29 08:20:23

Rust內存泄漏

2012-02-22 21:28:58

內存泄漏

2024-03-11 08:22:40

Java內存泄漏

2023-12-18 10:45:23

內存泄漏計算機服務器
點贊
收藏

51CTO技術棧公眾號

亚洲三级一区| 成视频在线观看免费观看| 日本а中文在线天堂| 久久精品xxx| 日韩av资源网| 亚洲精品福利资源站| 久草在线资源视频| 99久久国产综合精品色伊| 91精品国产综合久久香蕉的用户体验 | 亚洲自拍偷拍麻豆| 国产又爽又黄ai换脸| 91高清一区| 欧美亚洲第一页| 草莓视频成人appios| 日韩精品一区二区三区四区 | 亚洲亚洲精品三区日韩精品在线视频| 亚洲精品进入| 俺去了亚洲欧美日韩| 国产黄色大片在线观看| 狠狠久久五月精品中文字幕| 亚洲老女人av| av资源站一区| 欧美在线观看视频免费| 丝袜诱惑制服诱惑色一区在线观看| 国产日韩欧美成人| 亚洲制服一区| 欧美亚洲第一区| 欧美电影免费网站| 国产精品麻豆久久久| 少妇熟女一区二区| 久久国产精品毛片| 精品无人区一区二区三区| 国产大片一区| 日韩一区二区三区免费观看| 污导航在线观看| 亚洲色图一区二区三区| chinese少妇国语对白| 91影院在线免费观看| 北条麻妃在线视频观看| 日韩三级av| 久久久噜久噜久久综合| 日韩一区二区三区色| 久久久久久国产精品三级玉女聊斋| 男人午夜天堂| 亚洲理论在线观看| 日本特黄a级高清免费大片| 亚洲午夜激情网站| www国产精品内射老熟女| 欧美一区二区二区| 精品久久久无码人妻字幂| 精品中文字幕一区二区小辣椒 | 中文字幕一区二区不卡| 最近久乱中文字幕| 一级特黄大欧美久久久| 超碰在线中文| 欧美综合亚洲图片综合区| 麻豆视频免费在线观看| 亚洲国产高潮在线观看| 欧美在线一区视频| 成熟亚洲日本毛茸茸凸凹| 噜噜噜久久亚洲精品国产品麻豆| 91影院在线免费观看| 免费av手机在线观看| 91视视频在线观看入口直接观看www | 欧美成人在线免费视频| 女仆av观看一区| 国产综合色香蕉精品| 国产日韩欧美一区在线 | 成人午夜又粗又硬又大| www.日日操| 午夜精品成人在线| 18av在线视频| 在线成人激情黄色| 国产无遮挡在线视频免费观看| 一区二区三区精品久久久| 四虎精品成人影院观看地址| 制服丝袜亚洲精品中文字幕| 欧美日韩五区| 国产精品高清在线| 肉色丝袜一区二区| 国产精品久久久久久亚洲影视| 91视频精品| 日韩国产欧美精品| 久久五月婷婷丁香社区| 最新亚洲伊人网| 亚洲精品一区二区三区影院| 欧美电影在线观看一区| 成人高清在线观看| 成人激情文学综合网| 成人高清在线观看免费| 欧美一级高清片| 97精品久久| 久久久久久久有限公司| 92精品国产成人观看免费| 污视频在线观看网站| 久久成人久久爱| 青青草这里只有精品| 超碰免费公开在线| 国产综合视频| 国产在线制服美女| 精品久久国产97色综合| 国产亚洲精品v| 久9久9色综合| 欧美电影在线观看网站| 香蕉视频免费在线| 99re热在线观看| av资源在线观看免费高清| а√在线中文在线新版| 成人在线视频免费| 欧美成人ⅴideosxxxxx| 黑人巨茎大战欧美白妇| 中文字幕久热精品视频在线| 91视频在线看| 国产精品第十页| 91麻豆精品激情在线观看最新| 4444亚洲人成无码网在线观看 | 中文字幕精品网| 欧美日韩一区二区欧美激情 | 97在线视频免费看| 国产一区二区三区香蕉| 日韩电影不卡一区| 日韩有码一区| 精品一级视频| 欧美成人免费播放| 大胆人体一区二区| 成人涩涩视频| 飘雪影视在线观看免费观看| 2019一级黄色毛片免费看网| 欧美视频在线观看视频| 亚洲欧美激情另类校园| 国产精品99久| 亚洲网一区二区三区| 亚洲男人都懂的网站| 丁香五月网久久综合| 欧美日韩三级在线| 韩国一区二区在线观看| 欧美激情三区| 在线免费av网站| 九九久久久久99精品| 欧美日韩激情网| 国产精品乱人伦| 国产日韩精品一区二区三区| 凹凸日日摸日日碰夜夜爽1| 久久精品国产精品青草色艺 | 国产一区二区三区av在线| 国产一区欧美日韩| 国产欧美高清| 亚洲最大黄网| 999久久久免费精品国产| 99精品中文字幕在线不卡| 日韩综合一区| 亚洲高清不卡| 国产精品嫩草99av在线| 欧美1区视频| 黄色网页在线播放| 国产午夜福利100集发布| 最新欧美精品一区二区三区| 69堂精品视频在线播放| 在线视频不卡一区二区三区| 91精品婷婷国产综合久久性色| 欧美日韩国产在线一区| 91天堂在线| 国产精品激情自拍| 一区二区三区在线视频免费 | 国产黄色片在线播放| 成人黄色av播放免费| 日韩福利影院| 色综合天天综合| 欧美日韩视频一区二区三区| 成人免费在线电影| 免费影院在线观看一区| 69堂亚洲精品首页| 麻豆精品一区二区综合av| 大黄网站在线观看| 福利视频免费在线观看| 欧美成人免费全部观看天天性色| 中文字幕欧美区| 欧洲杯半决赛直播| 91精品大全| 99热这里只有精品7| 国产一区二区三区在线看| 91麻豆国产福利精品| 日韩精品福利一区二区三区| 中文字幕大看焦在线看| 免费在线一区二区| 欲色天天网综合久久| 国产精品二区一区二区aⅴ污介绍| 少妇精品久久久一区二区| 邻家有女韩剧在线观看国语| 日韩欧美一区二区三区久久婷婷| 中文字幕国产亚洲| 亚洲欧美日韩小说| 国产欧美一区二区三区国产幕精品| 欧美电影h版| 毛片毛片毛片毛片毛片毛片| 久久艳妇乳肉豪妇荡乳av| 在线亚洲男人天堂| 一区二区不卡在线视频 午夜欧美不卡在| 国产精品大片| 高清精品久久|