亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

ThreadLocal內(nèi)存泄漏問題解決方案

 更新時(shí)間:2020年09月15日 10:40:08   作者:小幾斤  
這篇文章主要介紹了ThreadLocal內(nèi)存泄漏問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

如果說(shuō) ThreadLocal 的話,那肯定就會(huì)涉及到內(nèi)存泄漏,為啥嘞

因?yàn)?吧啦吧啦 ~

ThreadLocal 解決了什么問題呢?

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

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

但是完全可以一個(gè)人一支筆對(duì)不對(duì),這樣的話,你填寫你的表格,我填寫我的表格,咱倆誰(shuí)都不耽擱誰(shuí)。這就是 ThreadLocal 在做的事情,因?yàn)槊總€(gè) Thread 都有一個(gè)副本,就不存在資源競(jìng)爭(zhēng),所以也就不需要加鎖,這不就是拿空間去換了時(shí)間嘛!

在開始之前,咱們先把 Thread, ThreadLocal, ThreadLocalMap 的關(guān)系捋一捋:

可以看到,在 Thread 中持有一個(gè) ThreadLocalMap , ThreadLocalMap 又是由 Entry 來(lái)組成的,在 Entry 里面有 ThreadLocal 和 value

ThreadLocal 為啥動(dòng)不動(dòng)就內(nèi)存泄漏呢?

在這里先給個(gè)解釋,后面咱們?cè)僭敿?xì)分析:

首先是因?yàn)?ThreadLocal 是基于 ThreadLocalMap 實(shí)現(xiàn)的,其中 ThreadLocalMap 的 Entry 繼承了 WeakReference ,而 Entry 對(duì)象中的 key 使用了 WeakReference 封裝,也就是說(shuō), Entry 中的 key 是一個(gè)弱引用類型,對(duì)于弱引用來(lái)說(shuō),它只能存活到下次 GC 之前

如果此時(shí)一個(gè)線程調(diào)用了 ThreadLocalMap 的 set 設(shè)置變量,當(dāng)前的 ThreadLocalMap 就會(huì)新增一條記錄,但由于發(fā)生了一次垃圾回收,這樣就會(huì)造成一個(gè)結(jié)果: key 值被回收掉了,但是 value 值還在內(nèi)存中,而且如果線程一直存在的話,那么它的 value 值就會(huì)一直存在

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

就是因?yàn)檫@條引用鏈的存在,就會(huì)導(dǎo)致如果 Thread 還在運(yùn)行,那么 Entry 不會(huì)被回收,進(jìn)而 value 也不會(huì)被回收掉,但是 Entry 里面的 key 值已經(jīng)被回收掉了

這只是一個(gè)線程,如果再來(lái)一個(gè)線程,又來(lái)一個(gè)線程…多了之后就會(huì)造成內(nèi)存泄漏

知道是怎么造成內(nèi)存泄漏之后,接下來(lái)要做的事情就好說(shuō)了,不是因?yàn)?value 值沒有被回收掉所以才會(huì)導(dǎo)致內(nèi)存泄露的嘛

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

ThreadLocal 是基于 ThreadLocalMap 實(shí)現(xiàn)的?

OK ,上面的內(nèi)容講完了,接下來(lái)一一來(lái)看

首先,你怎么知道 ThreadLocal 是基于 ThreadLocalMap 實(shí)現(xiàn)的呢?

從源碼知道的~

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

public class ThreadLocal<T> { 
  static class ThreadLocalMap { 
    static class Entry extends WeakReference<ThreadLocal<?>> { 
      /** The value associated with this ThreadLocal. */ 
      Object value; 
 
      Entry(ThreadLocal<?> k, Object v) { 
        super(k); 
        value = v; 
      } 
    } 
  } 
} }   } }

代碼中說(shuō)的很清楚了,在 ThreadLocal 內(nèi)部維護(hù)著 ThreadLocalMap ,而它的 Entry 則繼承自 WeakReference 的 ThreadLocal ,其中 Entry 的 k 為 ThreadLocal , v 為 Object ,在調(diào)用 super(k) 時(shí)就將 ThreadLocal 實(shí)例包裝成了一個(gè) WeakReference

強(qiáng)弱引用這塊內(nèi)容阿粉就直接放一個(gè)表格吧:

引用類型 功能特點(diǎn)
強(qiáng)引用 ( Strong Reference ) 被強(qiáng)引用關(guān)聯(lián)的對(duì)象永遠(yuǎn)不會(huì)被垃圾回收器回收掉
軟引用( Soft Reference ) 軟引用關(guān)聯(lián)的對(duì)象,只有當(dāng)系統(tǒng)將要發(fā)生內(nèi)存溢出時(shí),才會(huì)去回收軟引用引用的對(duì)象
弱引用 ( Weak Reference ) 只被弱引用關(guān)聯(lián)的對(duì)象,只要發(fā)生垃圾收集事件,就會(huì)被回收
虛引用 ( Phantom Reference ) 被虛引用關(guān)聯(lián)的對(duì)象的唯一作用是能在這個(gè)對(duì)象被回收器回收時(shí)收到一個(gè)系統(tǒng)通知

從表格中應(yīng)該能夠看出來(lái),弱引用的對(duì)象只要發(fā)生垃圾收集事件,就會(huì)被回收

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

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

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

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

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

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

假設(shè),假設(shè), ThreadLocal 使用的是強(qiáng)引用,會(huì)怎樣呢?

如果是強(qiáng)引用的話,在表格中也能夠看出來(lái),被強(qiáng)引用關(guān)聯(lián)的對(duì)象,永遠(yuǎn)都不會(huì)被垃圾回收器回收掉

如果引用的 ThreadLocal 對(duì)象被回收了,但是 ThreadLocalMap 還持有對(duì) ThreadLocal 的強(qiáng)引用,如果沒有 remove 的話, 在 GC 時(shí)進(jìn)行可達(dá)性分析, ThreadLocal 依然可達(dá),這樣就不會(huì)對(duì) ThreadLocal 進(jìn)行回收,但是我們期望的是引用的 ThreadLocal 對(duì)象被回收,這樣不就達(dá)不到目的了嘛

使用弱引用的話,雖然會(huì)出現(xiàn)內(nèi)存泄漏的問題,但是在 ThreadLocal 生命周期里面,都有對(duì) key 值為 null 時(shí)進(jìn)行回收的處理操作

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

啥?在 ThreadLcoal 生命周期里面,都有對(duì) key 值為 null 時(shí)進(jìn)行回收的處理操作?有證據(jù)么?

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Windows安裝Maven并配置環(huán)境的詳細(xì)步驟

    Windows安裝Maven并配置環(huán)境的詳細(xì)步驟

    Maven是一個(gè)非常流行的構(gòu)建和項(xiàng)目管理工具,用于Java開發(fā),它提供了一個(gè)強(qiáng)大的依賴管理系統(tǒng)和一系列標(biāo)準(zhǔn)化的構(gòu)建生命周期,本文將指導(dǎo)您如何在Windows操作系統(tǒng)上安裝和配置Maven,需要的朋友可以參考下
    2023-05-05
  • java實(shí)現(xiàn)手機(jī)短信驗(yàn)證的基本思路

    java實(shí)現(xiàn)手機(jī)短信驗(yàn)證的基本思路

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)手機(jī)短信驗(yàn)證的基本思路,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • 解決springboot+shiro+thymeleaf頁(yè)面級(jí)元素的權(quán)限控制問題

    解決springboot+shiro+thymeleaf頁(yè)面級(jí)元素的權(quán)限控制問題

    這篇文章主要介紹了解決springboot+shiro+thymeleaf頁(yè)面級(jí)元素的權(quán)限控制問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • java Split 實(shí)現(xiàn)去除一個(gè)空格和多個(gè)空格

    java Split 實(shí)現(xiàn)去除一個(gè)空格和多個(gè)空格

    這篇文章主要介紹了java Split 實(shí)現(xiàn)去除一個(gè)空格和多個(gè)空格,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2020-10-10
  • 一步步教你搭建Scala開發(fā)環(huán)境(非常詳細(xì)!)

    一步步教你搭建Scala開發(fā)環(huán)境(非常詳細(xì)!)

    Scala是一門基于jvm的函數(shù)式的面向?qū)ο缶幊陶Z(yǔ)言,擁有比java更加簡(jiǎn)潔的語(yǔ)法,下面這篇文章主要給大家介紹了關(guān)于搭建Scala開發(fā)環(huán)境的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • Java8 中使用Stream 讓List 轉(zhuǎn) Map使用問題小結(jié)

    Java8 中使用Stream 讓List 轉(zhuǎn) Map使用問題小結(jié)

    這篇文章主要介紹了Java8 中使用Stream 讓List 轉(zhuǎn) Map使用總結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-06-06
  • 詳細(xì)全面解析Java泛型

    詳細(xì)全面解析Java泛型

    這篇文章主要介紹了詳細(xì)全面解析Java泛型,java泛型主要提高了Java 程序的類型安全,通過知道使用泛型定義的變量的類型限制,編譯器可以驗(yàn)證類型假設(shè),消除源代碼中的許多強(qiáng)制類型轉(zhuǎn)換等多個(gè)有點(diǎn),下面我們進(jìn)入文章了解更多的詳細(xì)內(nèi)容吧
    2022-02-02
  • Spring?Security中如何獲取AuthenticationManager對(duì)象

    Spring?Security中如何獲取AuthenticationManager對(duì)象

    有時(shí)需要使用AuthenticationManager(以下簡(jiǎn)稱Manager)對(duì)象,可是這個(gè)對(duì)象不是Bean,沒有直接保存在Spring的Bean庫(kù)中,那么如何獲取Spring Security中的這個(gè)對(duì)象呢,需要的朋友可以參考下
    2022-11-11
  • springmvc直接不經(jīng)過controller訪問WEB-INF中的頁(yè)面問題

    springmvc直接不經(jīng)過controller訪問WEB-INF中的頁(yè)面問題

    這篇文章主要介紹了springmvc直接不經(jīng)過controller訪問WEB-INF中的頁(yè)面問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Spring如何消除代碼中的if-else/switch-case

    Spring如何消除代碼中的if-else/switch-case

    這篇文章主要給大家介紹了關(guān)于Spring如何消除代碼中if-else/switch-case的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04

最新評(píng)論