簡單明瞭,說說ThreadLocal記憶體洩漏

2021-10-06 03:24:33 字數 1543 閱讀 9100

首先,明確下存在洩漏可能的是哪個物件,看乙個使用threadlocal的例子:

沒錯,就是我標紅的new string("我是大物件"),被set到threadlocal中的物件

什麼叫記憶體洩漏呢?說直白點就是這個物件已經沒機會再被使用了,但是卻一直得不到**

在本例中,呼叫完testsetget()方法後,記憶體中的引用關係如下圖(實線表示強引用,虛線表示弱引用)

其中new threadlocal物件被兩個引用指向

1.我們自己使用的threadlocal引用,是乙個強引用

2.entry.key引用(thread對應的threadlocalmap的底層資料結構為entry),entry的key是乙個弱引用型別,從weakreference繼承來的

new string("我是大物件")物件被entry.value引用,entry.value是乙個強引用;因為threadlocalmap是thread的成員變數,所以其生命週期與thread一樣,只要thread不銷毀,除非這個強引用被置為null,否則就一直不會被**;

thread正常運轉時,entry.value只在兩種情況下會被置為null,1.顯式呼叫了threadlocal.remove(),2.執行threadlocalmap的get set方法中,當發現某個entry的key指向的是null時,就會將entry.v置為null

1的情況不需要討論,remove了就不存在洩漏問題了

2的情況,正是threadlocalmap將entry.key設定為weakreference型別的原因,設計者就是擔心使用者沒有執行threadlocal.remove就離開了,而thread還在跑著

這時候,前面說的threadlocal這個強引用已經失效,只剩下乙個entry.key指向new threadlocal物件,由於entry.key是弱引用,下次gc時,new threadlocal物件就會被帶走,entry.key就變成了null;

但此時new string("我是大物件")還在呢,還好設計者已經在threadlocalmap的set get方法中埋下了乾掉大物件的雷;

只要後續這個還在運轉的thread呼叫了任何乙個其他threadlocal變數的set get方法,new string("我是大物件")就會被乾掉,如果沒有,那就發生了記憶體洩漏,洩漏的時間範圍與這個thread的生命週期一致

插入排序(簡單明瞭)

class test public static void insertsort int a int m 1 從陣列的第二個位置開始遍歷值 for j 1 j 0 a i key 跳出迴圈 找到要插入的中間位置或已遍歷到0下標 system.out.println system.out.print ...

初識 Inject 註解 簡單明瞭

inject 註解可以出現在三種類成員之前,表示該成員需要注入依賴項。按執行時的處理順序這三種成員型別是 1 構造方法 2 方法 3 屬性 在構造方法上使用 inject 時,其引數在執行時由配置好的ioc容器提供。比如,在下面的 中,執行時呼叫murmurmessage類的構造方法時,ioc 容器...

簡單明瞭說明UDP打洞原理

為什麼需要打洞呢?主要是不同區域網的電腦,他們通過一台路由器連線internet上外網,由於不同區域網的電腦ip是內部ip,連線外網是通過內網的伺服器的路由器臨時分派乙個通訊埠實現的,區域網路內部的電腦並不是真正internet上的乙個節點,這樣不同區域網路的電腦肯定無法通過internet直接通訊...