大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

如何理解 Java 中的弱引用?


  在如今Java軟件開發中,平均20多個有著5年開發經驗和高學歷背景的應聘者中,居然只有可憐的兩個人知道弱引用的存在,但是在這兩個人中,可能只有一個真正的了解這方面的知識,更大的可能性是所有人都不知道弱引用的存在。接下來由動力節點Java培訓的老師來為大家介紹一下引用與弱引用究竟是什么?

 

  強引用(StrongReference)

 

  強引用就是我們經常使用的引用,其寫法如下

 

  1StringBufferbuffer=newStringBuffer();

 

  上面創建了一個StringBuffer對象,并將這個對象的(強)引用存到變量buffer中。是的,就是這個小兒科的操作(請原諒我這樣的說法)。強引用重要的就是它能夠讓引用變得強(Strong),這就決定了它和垃圾回收器的交互。具體來說,如果一個對象通過一串強引用鏈接可到達(Stronglyreachable),它是不會被回收的。如果你不想讓你正在使用的對象被回收,這就正是你所需要的。

 

  但是強引用如此之強

 

  在一個程序里,將一個類設置成不可被擴展是有點不太常見的,當然這個完全可以通過類標記成final實現。或者也可以更加復雜一些,就是通過內部包含了未知數量具體實現的工廠方法返回一個接口(Interface)。舉個例子,我們想要使用一個叫做Widget的類,但是這個類不能被繼承,所以無法增加新的功能。

 

  但是我們如果想追蹤Widget對象的額外信息,我們該怎么辦?假設我們需要記錄每個對象的序列號,但是由于Widget類并不包含這個屬性,而且也不能擴展導致我們也不能增加這個屬性。其實一點問題也沒有,HashMap完全可以解決上述的問題。

 

  1serialNumberMap.put(widget,widgetSerialNumber);

 

  這表面看上去沒有問題,但是widget對象的強引用很有可能會引發問題。我們可以確信當一個widget序列號不需要時,我們應該將這個條目從map中移除。如果我們沒有移除的話,可能會導致內存泄露,亦或者我們手動移除時刪除了我們正在使用的widgets,會導致有效數據的丟失。其實這些問題很類似,這就是沒有垃圾回收機制的語言管理內存時常遇到的問題。但是我們不用去擔心這個問題,因為我們使用的時具有垃圾回收機制的Java語言。

 

  另一個強引用可能帶來的問題就是緩存,尤其是像圖片這樣的大文件的緩存。假設你有一個程序需要處理用戶提供的圖片,通常的做法就是做圖片數據緩存,因為從磁盤加載圖片代價很大,并且同時我們也想避免在內存中同時存在兩份一樣的圖片數據。

 

  緩存被設計的目的就是避免我們去再次加載哪些不需要的文件。你會很快發現在緩存中會一直包含一個到已經指向內存中圖片數據的引用。使用強引用會強制圖片數據留在內存,這就需要你來決定什么時候圖片數據不需要并且手動從緩存中移除,進而可以讓垃圾回收器回收。因此你再一次被強制做垃圾回收器該做的工作,并且人為決定是該清理到哪一個對象。

 

  弱引用(WeakReference)

 

  弱引用簡單來說就是將對象留在內存的能力不是那么強的引用。使用WeakReference,垃圾回收器會幫你來決定引用的對象何時回收并且將對象從內存移除。創建弱引用如下

 

  1WeakReference<Widget>weakWidget=newWeakReference<Widget>(widget);

 

  使用weakWidget.get()就可以得到真實的Widget對象,因為弱引用不能阻擋垃圾回收器對其回收,你會發現(當沒有任何強引用到widget對象時)使用get時突然返回null。

 

  解決上述的widget序列數記錄的問題,簡單的辦法就是使用Java內置的WeakHashMap類。WeakHashMap和HashMap幾乎一樣,僅有的區別就是它的鍵(不是值!!!)使用WeakReference引用。當WeakHashMap的鍵標記為垃圾的時候,這個鍵對應的條目就會自動被移除。這就避免了上面不需要的Widget對象手動刪除的問題。使用WeakHashMap可以很便捷地轉為HashMap或者Map。

 

  引用隊列(ReferenceQueue)

 

  一旦弱引用對象開始返回null,該弱引用指向的對象就被標記成了垃圾。而這個弱引用對象(非其指向的對象)就沒有什么用了。通常這時候需要進行一些清理工作。比如WeakHashMap會在這時候移除沒用的條目來避免保存無限制增長的沒有意義的弱引用。

 

  引用隊列可以很容易地實現跟蹤不需要的引用。當你在構造WeakReference時傳入一個ReferenceQueue對象,當該引用指向的對象被標記為垃圾的時候,這個引用對象會自動地加入到引用隊列里面。接下來,你就可以在固定的周期,處理傳入的引用隊列,比如做一些清理工作來處理這些沒有用的引用對象。

 

  四種引用

 

  Java中實際上有四種強度不同的引用,從強到弱它們分別是,強引用,軟引用,弱引用和虛引用。上面部分介紹了強引用和弱引用,下面介紹剩下的兩個,軟引用和虛引用。

 

  軟引用(SoftReference)

 

  軟引用基本上和弱引用差不多,只是相比弱引用,它阻止垃圾回收期回收其指向的對象的能力強一些。如果一個對象是弱引用可到達,那么這個對象會被垃圾回收器接下來的回收周期銷毀。但是如果是軟引用可以到達,那么這個對象會停留在內存更時間上長一些。當內存不足時垃圾回收器才會回收這些軟引用可到達的對象。

 

  由于軟引用可到達的對象比弱引用可達到的對象滯留內存時間會長一些,我們可以利用這個特性來做緩存。這樣的話,你就可以節省了很多事情,垃圾回收器會關心當前哪種可到達類型以及內存的消耗程度來進行處理。

 

  虛引用(PhantomReference)

 

  與軟引用,弱引用不同,虛引用指向的對象十分脆弱,我們不可以通過get方法來得到其指向的對象。它的作用是當其指向的對象被回收之后,自己被加入到引用隊列,用作記錄該引用指向的對象已被銷毀。

 

  當弱引用的指向對象變得弱引用可到達,該弱引用就會加入到引用隊列。這一操作發生在對象析構或者垃圾回收真正發生之前。理論上,這個即將被回收的對象是可以在一個不符合規范的析構方法里面重新復活。但是這個弱引用會銷毀。虛引用只有在其指向的對象從內存中移除掉之后才會加入到引用隊列中。其get方法一直返回null就是為了阻止其指向的幾乎被銷毀的對象重新復活。

 

  虛引用使用場景主要由兩個。它允許你知道具體何時其引用的對象從內存中移除。而實際上這是Java中僅有的方式。這一點尤其表現在處理類似圖片的大文件的情況。當你確定一個圖片數據對象應該被回收,你可以利用虛引用來判斷這個對象回收之后在繼續加載下一張圖片。這樣可以盡可能地避免可怕的內存溢出錯誤。

 

  第二點,虛引用可以避免很多析構時的問題。finalize方法可以通過創建強引用指向快被銷毀的對象來讓這些對象重新復活。然而,一個重寫了finalize方法的對象如果想要被回收掉,需要經歷兩個單獨的垃圾收集周期。在第一個周期中,某個對象被標記為可回收,進而才能進行析構。但是因為在析構過程中仍有微弱的可能這個對象會重新復活。這種情況下,在這個對象真實銷毀之前,垃圾回收器需要再次運行。因為析構可能并不是很及時,所以在調用對象的析構之前,需要經歷數量不確定的垃圾收集周期。這就意味著在真正清理掉這個對象的時候可能發生很大的延遲。這就是為什么當大部分堆被標記成垃圾時還是會出現煩人的內存溢出錯誤。

 

  使用虛引用,上述情況將引刃而解,當一個虛引用加入到引用隊列時,你沒有辦法得到一個銷毀了的對象。因為這時候,對象已經從內存中銷毀了。因為虛引用不能被用作讓其指向的對象重生,所以其對象會在垃圾回收的第一個周期就將被清理掉。

 

  顯而易見,finalize方法不建議被重寫。因為虛引用明顯地安全高效,去掉finalize方法可以虛擬機變得明顯簡單。當然你也可以去重寫這個方法來實現更多,這完全看個人選擇。

 

  

 

上一篇: 為什么很多人說Java培訓不靠譜
下一篇: 學Java解決困難的較快方法是什么

開班信息

主站蜘蛛池模板: 老妇综合久久香蕉蜜桃 | 国内久久久久高清影视 | 亚洲欧美成人综合 | 日韩a一级欧美一级在线播放 | 欧美影院一区二区 | 国产伦一区二区三区免费 | 欧美一级高清在线观看 | 国产区一区二区三区 | 欧美日韩亚洲m码色帝国 | 精品精品国产高清a毛片 | 九九热精彩视频 | av毛片免费看| 欧美精品毛片 | 色综合久久中文字幕综合网 | 亚洲黄色片视频 | 成人午夜影院在线观看 | 加勒比啪啪 | 欧美japanese孕交| 在线播放亚洲 | 国产精品欧美一区二区在线看 | 亚洲国产精品高清在线一区 | 香香影院在线观看 | 京野结衣免费一区二区 | 天天干天天玩天天操 | 国产一级特黄老妇女大片免费 | 久久桃花网 | 欧美日穴 | 老司机一级毛片 | 在线资源站 | 久久亚洲精品国产亚洲老地址 | 日韩一级视频免费观看 | 久久国产免费福利永久 | 日本不卡二 | 91免费国产在线观看尤物 | 男女啪啪猛烈免费网站 | 日韩精品在线一区 | 99热这里只有精品8 99热这里只有精品88 | 亚洲精品久久午夜香蕉 | 免费观看男女羞羞的视频网站 | 国产涩| 日本在线观看一级高清片 |