Q1:引用隊列是什么?如何使用?使用的場景有哪些?
A1:oracle的api文檔的描述:
https://docs.oracle.com/javase/7/docs/api/java/lang/ref/ReferenceQueue.htmlReference queues, to which registered reference objects are appended by the garbage collector after the appropriate reachability changes are detected.
當對象的可及性的改變被GC發現時,與之相關聯的(registered)的reference object會被加入該隊列。
Q2:java的heap是什么?
A2:如圖所示,Heap和Stack分別負責存儲不同類型的數據。
Stack區用於存儲基本數據類型和對象的引用;而Heap區存儲對象的實例。
Stack區的讀寫很快但缺點是數據的生存期和大小都是固定的,而Heap則可以動態申請內存。
具體內容很多,以后單獨寫上。
在Java里, 當一個對象o被創建時, 它被放在Heap里. 當GC運行的時候, 如果發現沒有任何引用指向o, o就會被回收以騰出內存空間. 或者換句話說, 一個對象被回收, 必須滿足兩個條件:
- 沒有任何引用指向它
- GC被運行.
強引用:
強引用不會被GC回收,並且在java.lang.ref里也沒有實際的對應類型,平時工作接觸的最多的就是強引用。Object obj = new Object();這里的obj引用便是一個強引用。如果一個對象具有強引用,那就類似於必不可少的生活用品,垃圾回收器絕不會回收它。 當內存空間不足,Java虛擬機寧願拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足問題。
軟引用:如果一個對象只具有軟引用,那就類似於可有可物的生活用品。如果內存空間足夠,垃圾回收器就不會回收它,如果內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實現內存敏感的高速緩存。軟引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果軟引用所引用的對象被垃圾回收,Java虛擬機就會把這個軟引用加入到與之關聯的引用隊列中。
弱引用:
弱引用(weak reference)在強度上弱於軟引用,通過類WeakReference來表示。它的作用是引用一個對象,但是並不阻止該對象被回收。如果使用一個強引用的話,只要該引用存在,那么被引用的對象是不能被回收的。弱引用則沒有這個問題。在垃圾回收器運行的時候,如果一個對象的所有引用都是弱引用的話,該對象會被回收。弱引用的作用在於解決強引用所帶來的對象之間在存活時間上的耦合關系。弱引用最常見的用處是在集合類中,尤其在哈希表中。哈希表的接口允許使用任何Java對象作為鍵來使用。當一個鍵值對被放入到哈希表中之后,哈希表對象本身就有了對這些鍵和值對象的引用。如果這種引用是強引用的話,那么只要哈希表對象本身還存活,其中所包含的鍵和值對象是不會被回收的。如果某個存活時間很長的哈希表中包含的鍵值對很多,最終就有可能消耗掉JVM中全部的內存。
對於這種情況的解決辦法就是使用弱引用來引用這些對象,這樣哈希表中的鍵和值對象都能被垃圾回收。Java中提供了WeakHashMap來滿足這一常見需求。
虛引用:
在介紹幽靈引用之前,要先介紹Java提供的對象終止化機制(finalization)。在Object類里面有個finalize方法,其設計的初衷是在一個對象被真正回收之前,可以用來執行一些清理的工作。因為Java並沒有提供類似C++的析構函數一樣的機制,就通過 finalize方法來實現。但是問題在於垃圾回收器的運行時間是不固定的,所以這些清理工作的實際運行時間也是不能預知的。幽靈引用(phantom reference)可以解決這個問題。在創建幽靈引用PhantomReference的時候必須要指定一個引用隊列。當一個對象的finalize方法已經被調用了之后,這個對象的幽靈引用會被加入到隊列中。通過檢查該隊列里面的內容就知道一個對象是不是已經准備要被回收了。
幽靈引用及其隊列的使用情況並不多見,主要用來實現比較精細的內存使用控制,這對於移動設備來說是很有意義的。程序可以在確定一個對象要被回收之后,再申請內存創建新的對象。通過這種方式可以使得程序所消耗的內存維持在一個相對較低的數量。
相關鏈接:
http://blog.csdn.net/weizaishouex2010/article/details/49002913
http://stackoverflow.com/questions/14450538/using-javas-referencequeue(stackoverflow上講的弱引用和引用隊列的應用場景)