四種引用類型

四種引用類型

強引用:

強引用又稱‘普通引用’,如:T t = new T();

這種引用類型永遠都不會被回收。

軟引用:

SoftReference<T>  m = new SoftReference<>(new T());

此種引用只有在內存不足的情況下回收,一般用於緩存對象、圖片等對象,用完一次就不用的場景。

弱引用:

WeakReference<T>  m = new WeakReference<>(new T());

弱引用在調用 System.gc();時就會回收。

一般用在容器裏,如ThreadLocal:

ThreadLocal 往裏set值的時候,是往當前線程的Map 中放數據,key就是ThreadLocal對象,value是具體對象,在往map中set(確實是set)的時候,其實是一個Entry對象,這個Entry對象就繼承了WeakReference類,是一個弱引用,噹噹前線程結束的時候,此時的key也就是ThreadLocal對象就會自動被回收。

 

如果這個key不是弱引用,而是強引用,在當前線程結束的時候,這個key,也就是ThreadLocal對象是不會被回收的。會導致內存泄露。

 

 

所以,使用ThreadLocal,不用以後,必須把對象remove掉。

 

WeakHashMap???

虛引用:

虛引用主要用於堆外內存的。

PhantomReference<T> m = new PhantomReference<>(new T(),QUEUE);

這個東西是給寫虛擬機(JVM)的人用的,程序員一般用不上。

垃圾回收只要看到有虛引用,二話不說,直接回收。當對象被回收的時候,會通知你,將對象的引用放入QUEUE 中,也就是說,只要隊列中有引用,說明這個對象已被回收。

還有一點,虛引用裏邊的值是get不到的。

NIO中有個DirectByteBuffer就是堆外內存(直接內存),使用的虛引用,它不歸JVM管理,而是操作系統,什麼時候去回收這塊堆外內存呢?可以去監聽這個隊列,當這個隊列中有值時,就去清理堆外內存。

怎麼回收堆外內存?

通過Unsafe,還有直接分配內存、釋放內存的api

 

 

 

內存泄露和內存溢出的區別:

內存泄露可以理解爲 漏掉了一塊,永遠不會被回收;內存溢出是指佔用的內存越來越多,佔不下了導致溢出。

 

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