ThreadLocal內存泄露原因,如何避免


內存泄漏為程序在申請內存后,無法釋放已申請的內存空間,一次泄露危害可以忽略,但內存泄漏堆積后果很嚴重,無論多少內存,遲早會被占光。

不再會被使用的對象或者變量占用的內存空間不能被回收,就是內存泄漏。

強引用:使用最普遍的一個引用(new),一個對象具有強引用,不會被垃圾收集器回收。當內存空間不足,java虛擬機寧願OOM,都不會回收。

如果想取消強引用和某個對象之間的關聯,可以顯示將對象復制為null,這樣jvm就會在安全區域執行gc進行垃圾回收。

弱引用:jvm進行垃圾回收時,無論內存是否充足,都會回收被弱引用關聯的對象。在java中,用WeakReference類來表示。

ThreadLocal的實現原理,每一個Thread維護一個ThreadLocalMap,ThreadLocalMap是由一個個Entry構成,而Entry繼承了弱引用,key為使用弱引用的ThreadLocal對象,value為線程變量的副本。


ThreadLocalMap使用ThreadLocal的弱引用作為key,如果一個ThreadLocal不存在外部的強引用時,Key(ThreadLocal對象)勢必會被GC回收,這樣就會導致ThreadLocalMap中的key為null,而value還存在着強引用,只有thread線程退出以后,value的強引用鏈才會斷掉,但是如果線程遲遲不結速的話,這些key為null的Entry的value就會一直存在引用鏈。

key使用強引用
當ThreadLocalMap的key使用強引用時,此時若是外部的ThreadLocal對象被置為null,按理說應該被回收,但是ThreadLocalMap中還持有對ThreadLocal的強引用,如果沒有手動刪除,那么ThreadLocal不會被回收,導致Entry內存泄漏。

key使用弱引用
當ThreadLocalMap的key為弱引用回收ThreadLocal對象時,由於ThreadLocalMap只持有ThreadLocal的弱引用,即使沒有手動刪除,也不會影響ThreadLocal的回收。當key為null時,在下一個調用ThreadLocalMap的set、get、remove方法時會清除value值。

ThreadLocal正確使用方法

  • 每次使用完ThreadLocal都調用它的remove方法清楚數據
  • 將ThreadLocal變量定義為private static,這樣就一直存在ThreadLocal的強引用,也就能保證在任何時候都能通過ThreadLocal的弱引用訪問到Entry的value值,繼續清除。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM