強軟弱虛引用以及threadlocal

又是一個被講爛的東西,但是我還是總結一下,日後也可以自己看。

一、強引用

A a = new A(); a是強引用,new A();是對象。我們99%都是用這樣形式,不多說,不舉例。

二、軟引用

軟引用是說當內存不足時,也就是快oom之前,它會去把只有軟引用引用的對象刪除。例子如下:

結果如下:

三、弱引用

弱引用是說當第一次GC時候,刪除只有弱引用引用的對象。例子如下:

結果如下:

四、虛引用(幽靈引用)

虛引用在任何時間都可能被刪除,而且無論何時使用get方法都會返回null。他必須搭配RefrenceQueue使用,除了虛引用,軟引用和弱引用都可以使用RefrenceQueue,而且用法都一樣。這裏就用虛引用做例子。例子如下:

結果如下:

五、threadlocal之oom

很多同行發博客我覺得已經失去了初心,我認爲這是一個做技術人最純粹的東西,但是現在很多人沒有搞清楚或者複製別人的貼子,也許這也是大家認爲谷歌比百度好的原因,但我不管環境怎麼樣,我的文章一定是原創,一定是我驗證過的。

threadlocal裏有個threadlocalmap,這個map自定義了一個entry,這個entry key是弱引用,value是threadlocal的值。

1、如果你用如下方式用threadlocal(我們大多數也是這麼用的,阿里的java開發規範也是建議這麼用的)

這裏threadlocal是一個靜態私有的成員變量,我們之前有說過弱引用只有當對象只有弱引用時候纔會被GC清除,那麼這樣寫就是有一個強引用,那麼就不會出現很多文章說的出現key爲null,value有值的entry。但是這樣也會oom,比如線程太多,每個線程放到threadllocal裏數據太大,也會oom。這裏是oom第一個原因。

2、如果採用私有變量,那麼會出現網上大部分文章說的key爲null,從而導致oom的情況

原因解釋:這裏設置了threadlocal並且賦了值,但是他沒有強引用。那麼當第一次GC,時候entry裏的key會被清空,value保留值。但是僅僅這樣也是不會oom,還要有2個條件。

①就是所運行的線程不能結束,因爲線程結束threadlocalmap也沒了,自然不會oom。

②線程運行過程中不再執行set、get、remove命令

當線程運行過程中發生了GC,那麼會留下一個空key的entry。並且沒有執行set、get、remove,因爲這3個命令都會清空key爲null的entry。當滿足這兩個條件,請求線程再多一點,就會出現oom了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章