日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

GuavaCache学习笔记二:Java四大引用类型回顾

發布時間:2024/4/17 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GuavaCache学习笔记二:Java四大引用类型回顾 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

上一篇已經講了,如何自己實現一個LRU算法。但是那種只是最基本的實現了LRU的剔除策略,并不能在生產中去使用。因為Guava Cache中使用的是SoftReference去做的value實現,所以有必要將Java的四種引用類型在復習一下。

備注:以下代碼使用的JVM配置為:
-Xmx128M -Xms64M -XX:+PrintGCDetails

Java的四種引用

強引用(StrongReference)

強引用是使用最普遍的引用。如果一個對象具有強引用,那垃圾回收器絕不會回收它。如下:
Object o=new Object(); // 強引用
當內存空間不足,Java虛擬機寧愿拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足的問題。如果不使用時,要通過如下方式來弱化引用,如下:
o=null; // 幫助垃圾收集器回收此對象
顯式地設置o為null,或超出對象的生命周期范圍,則gc認為該對象不存在引用,這時就可以回收這個對象。具體什么時候收集這要取決于gc的算法。

軟引用 (SoftReference)

如果一個對象只具有軟引用,則內存空間足夠,垃圾回收器就不會回收它;如果內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實現內存敏感的高速緩存。

看例子:

/*** @Description: 模擬Java四種引用類型的方法* @Author: wangmeng* @Date: 2018/12/8-11:10*/ public class ReferenceExample {public static void main(String[] args) throws Exception{/*** SoftReference:判斷JVM快要溢出的時候,JVM GC時會判斷有沒有SoftReference數據*/int counter = 0;List<SoftReference<Ref>> container = Lists.newArrayList();for (;;) {int current = counter++;container.add(new SoftReference<>(new Ref(current)));System.out.println("The " + current + " Ref will be insert into container");TimeUnit.MILLISECONDS.sleep(50);}private static class Ref {//調用Ref的時候,每次都new出來一個lM的byte,模擬觸發GCprivate byte[] data = new byte[1024 * 1024];private final int index;private Ref(int index) {this.index = index;}@Overrideprotected void finalize() throws Throwable {System.out.println("The index [" + index + "] will be GC.");}} }


可以看到上面的輸出結果,到了后面仍然OOM了,因為我們這里設置的執行時間是50ms,雖然內存不足時進行了GC操作,但是由于放入的速度過快,所以還是OOM了。
這里要展示的是,當內存不足的時候,垃圾回收就會回收軟引用的內容來防止OOM,但是這樣并不能百分百避免OOM。

弱引用(WeakReference)

弱引用與軟引用的區別在于:只具有弱引用的對象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存。不過,由于垃圾回收器是一個優先級很低的線程,因此不一定會很快發現那些只具有弱引用的對象。
弱引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果弱引用所引用的對象被垃圾回收,Java虛擬機就會把這個弱引用加入到與之關聯的引用隊列中。當你想引用一個對象,但是這個對象有自己的生命周期,你不想介入這個對象的生命周期,這時候你就是用弱引用。這個引用不會在對象的垃圾回收判斷中產生任何附加的影響。

/*** @Description: 模擬Java四種引用類型的方法* @Author: wangmeng* @Date: 2018/12/8-11:10*/ public class ReferenceExample {public static void main(String[] args) throws Exception{/*** Weak reference: 當GC的時候就會被回收*/int counter = 0;List<WeakReference<Ref>> container = Lists.newArrayList();for (;;) {int current = counter++;container.add(new WeakReference<>(new Ref(current)));System.out.println("The " + current + " Ref will be insert into container");TimeUnit.MILLISECONDS.sleep(50);}}private static class Ref {//調用Ref的時候,每次都new出來一個lM的byte,模擬觸發GCprivate byte[] data = new byte[1024 * 1024];private final int index;private Ref(int index) {this.index = index;}@Overrideprotected void finalize() throws Throwable {System.out.println("The index [" + index + "] will be GC.");}} }

執行結果如圖,可見在GC運行時必定會對弱引用進行回收。

虛引用(PhantomReference)

“虛引用”顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用并不會決定對象的生命周期。如果一個對象僅持有虛引用,那么它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。
虛引用主要用來跟蹤對象被垃圾回收器回收的活動。虛引用與軟引用和弱引用的一個區別在于:虛引用必須和引用隊列 (ReferenceQueue)聯合使用。當垃圾回收器準備回收一個對象時,如果發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之 關聯的引用隊列中。

/*** @Description: 模擬Java四種引用類型的方法* @Author: wangmeng* @Date: 2018/12/8-11:10*/ public class ReferenceExample {public static void main(String[] args) throws Exception{/*** PhantomReference 中有一個最佳實踐,可以通過查看:org.apache.commons.io.FileCleaningTracker查看** 虛引用起到一個通知作用*/Ref ref = new Ref(10);ReferenceQueue queue = new ReferenceQueue<>();MyPhantomReference reference = new MyPhantomReference(ref, queue, 10);ref = null;System.out.println(reference.get());System.gc();Reference remove = queue.remove();((MyPhantomReference)remove).doAction();}private static class MyPhantomReference extends PhantomReference<Object> {private int index;public MyPhantomReference(Object referent, ReferenceQueue<? super Object> q, int index) {super(referent, q);this.index = index;}public void doAction() {System.out.println("The object " + index + " is GC");}}private static class Ref {//調用Ref的時候,每次都new出來一個lM的byte,模擬觸發GCprivate byte[] data = new byte[1024 * 1024];private final int index;private Ref(int index) {this.index = index;}@Overrideprotected void finalize() throws Throwable {System.out.println("The index [" + index + "] will be GC.");}} }

使用jconsole,點擊執行GC,這時可以看到其實打印了PhantomReference中的數據。

總結

以上代碼在我的github可以看到:
我的github地址
可參見cn.barrywangmeng.cache.reference.ReferenceExample



來自為知筆記(Wiz)

轉載于:https://www.cnblogs.com/wang-meng/p/20bcc1ea5a9822fe3398531594062068.html

總結

以上是生活随笔為你收集整理的GuavaCache学习笔记二:Java四大引用类型回顾的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。