Java中幾個Reference作用,也是面試的時候經(jīng)常問到的問題,以前總是記一次忘一次,現(xiàn)在有時間,索性寫個demo測試一把。
具體代碼如下:
JVM 參數(shù):-Xmx10m -Xms5m -XX:+PrintGC
SoftReference的時候:
weakReference的時候:
StrongReference:
由于strong是JVM默認的,這里就不做了,直接就是一點都不會被回收,直至OOM
PhantomReference:
虛引用并不會改變內(nèi)存回收機制,只是在回收的時候放到ReferenceQueue里通知用戶可做一些額外操作,比如打印日志等
如下代碼,本質(zhì)上byte[]還是一個強引用的。
輸出:
總結(jié)一下:
StrongReference:JVM默認,除非GC時已無任何對象引用,否則即便是OOM也不會回收
WeakReference:一旦沒有被引用,GC時就會回收
SoftReference:和strong一樣,除非GC時已無任何對象引用,否則....在即將OOM前才會被回收,所以SoftReference一般可以用來做緩存
sun.nio.ch.Util中就有private static ThreadLocal<SoftReference<SelectorWrapper>> localSelector
= new ThreadLocal<SoftReference<SelectorWrapper>>();
用于臨時的Selector。
PhantomReference:通過構(gòu)造函數(shù)的ReferenceQueue作為一個通知,用來在對象被回收時做額外的操作。
更新:
對于weakReference的理解有偏差,上面的測試和strongReference沒啥差別,重新加了測試:
上圖中不將b的引用去除掉(b=null),增加循環(huán)
結(jié)果:
執(zhí)行了2次不同的循環(huán)次數(shù)后jvm執(zhí)行g(shù)c,這時將wr中的byte[]回收掉。
- WeakReference的一個特點是它何時被回收是不可確定的, 因為這是由GC運行的不確定性所確定的. 所以, 一般用weak reference引用的對象是有價值被cache, 而且很容易被重新被構(gòu)建, 且很消耗內(nèi)存的對象.
總結(jié)來說wr是一種比sr更弱的緩存,當某些對象最好能被緩存,但是重新構(gòu)建問題也不大的情況下可以使用。