中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何探究ThreadLocal內存泄漏的原因

發布時間:2021-12-17 14:34:17 來源:億速云 閱讀:319 作者:柒染 欄目:大數據

本篇文章給大家分享的是有關如何探究ThreadLocal內存泄漏的原因,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

1、首先看下ThreadLocal的原理圖:

在ThreadLocal的生命周期中,都存在這些引用。

如何探究ThreadLocal內存泄漏的原因

其中,實線代表強引用,虛線代表弱引用;

2、ThreadLocal的實現:每個Thread維護一個ThreadLocalMap映射表,這個映射表的key是ThreadLocal實例本身,value是真正需要存儲的Object;

3、也就是說ThreadLocal本身不存儲值,它只是作為一個key來讓線程從ThreadLocalMap獲取value,值得注意的是圖中的虛線,表示ThreadLocalMap是使用ThreadLocal的弱引用作為key,其在GC時會被回收;

4、ThreadLocalMap使用ThreadLocal的弱引用作為key,如果一個ThreadLocal沒有外部強引用來引用它,那么系統 GC 的時候,這個ThreadLocal勢必會被回收,這樣一來,ThreadLocalMap中就會出現key為null的Entry,就沒有辦法訪問這些key為null的Entry的value,如果當前線程再遲遲不結束的話,這些key為null的Entry的value就會一直存在一條強引用鏈:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永遠無法回收,造成內存泄漏。

5、總的來說就是,ThreadLocal里面使用了一個存在弱引用的map, map的類型是ThreadLocal.ThreadLocalMap. Map中的key為一個threadlocal實例。這個Map的確使用了弱引用,不過弱引用只是針對key。每個key都弱引用指向threadlocal。當把threadlocal實例置為null以后,沒有任何強引用指向threadlocal實例,所以threadlocal將會被gc回收。

但是,我們的value卻不能回收,而這塊value永遠不會被訪問到了,所以存在著內存泄露。因為存在一條從current thread連接過來的強引用。只有當前thread結束以后,current thread就不會存在棧中,強引用斷開,Current Thread、Map value將全部被GC回收。最好的做法是將調用threadlocal的remove方法,這也是等會后邊要說的。

6、其實,ThreadLocalMap的設計中已經考慮到這種情況,也加上了一些防護措施:在ThreadLocal的get(),set(),remove()的時候都會清除線程ThreadLocalMap里所有key為null的value。這一點在上一節中也講到過!

7、但是這些被動的預防措施并不能保證不會內存泄漏:

a、使用static的ThreadLocal,延長ThreadLocal的生命周期,可能導致內存泄漏;

b、分配只用了ThreadLocal又不再調用get()、set()、remove()方法,那么可能導致內存泄漏,因為這塊內存會一直存在;

以下是源碼:

/**
 * The entries in this hash map extend WeakReference, using
 * its main ref field as the key (which is always a
 * ThreadLocal object). Note that null keys (i.e. entry.get()
 * == null) mean that the key is no longer referenced, so the
 * entry can be expunged from table. Such entries are referred to
 * as "stale entries" in the code that follows.
 */
static class Entry extends WeakReference<ThreadLocal<?>> {
     /** The value associated with this ThreadLocal. */
     Object value;
     Entry(ThreadLocal<?> k, Object v) {
     super(k);
     value = v;
     }
}

以上就是如何探究ThreadLocal內存泄漏的原因,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汝城县| 资中县| 荣成市| 阿巴嘎旗| 福州市| 新野县| 宁波市| 泰和县| 长寿区| 江西省| 航空| 西华县| 五常市| 宾川县| 金阳县| 大兴区| 泗阳县| 诸城市| 青海省| 长岭县| 龙海市| 鹰潭市| 通化县| 天长市| 洛阳市| 瑞昌市| 西丰县| 巴彦淖尔市| 聊城市| 衡山县| 常熟市| 英超| 渭南市| 阳东县| 鲁山县| 海门市| 广河县| 桂东县| 武川县| 江川县| 民乐县|