1. 什么是引用?
問題:什么是引用?Java中的引用是如何工作的?
答案:
- 引用 是對象的句柄,用于訪問堆內存中的對象。
- 在Java中,引用變量實際上存儲的是對象的地址,而不是對象本身。
- 通過引用,可以訪問對象的屬性和方法。
2. Java中的引用類型有哪些?
問題:Java中有哪幾種引用類型?
答案:
- 強引用(Strong Reference):最常見的引用類型,如
Object obj = new Object()
。只要強引用存在,垃圾回收器就不會回收被引用的對象。 - 軟引用(Soft Reference):通過
SoftReference
類實現。在內存不足時,垃圾回收器會回收軟引用指向的對象。 - 弱引用(Weak Reference):通過
WeakReference
類實現。垃圾回收器在每次垃圾回收時都會回收弱引用指向的對象。 - 虛引用(Phantom Reference):通過
PhantomReference
類實現。虛引用不會影響對象的生命周期,主要用于在對象被垃圾回收時收到通知。
3. 強引用和軟引用有什么區別?
問題:強引用和軟引用有什么區別?
答案:
- 強引用:只要強引用存在,垃圾回收器就不會回收被引用的對象。即使內存不足,也不會回收強引用的對象,可能會導致
OutOfMemoryError
。 - 軟引用:在內存不足時,垃圾回收器會回收軟引用指向的對象。軟引用通常用于實現內存敏感的緩存。
4. 什么是弱引用?它的應用場景是什么?
問題:什么是弱引用?它的應用場景是什么?
答案:
- 弱引用:通過
WeakReference
類實現。垃圾回收器在每次垃圾回收時都會回收弱引用指向的對象。 - 應用場景:
- 緩存:用于實現內存敏感的緩存,當內存不足時,可以自動釋放緩存對象。
- 監聽器:在事件處理中,為了避免內存泄漏,可以使用弱引用來存儲監聽器。
5. 什么是虛引用?它的應用場景是什么?
問題:什么是虛引用?它的應用場景是什么?
答案:
- 虛引用:通過
PhantomReference
類實現。虛引用不會影響對象的生命周期,主要用于在對象被垃圾回收時收到通知。 - 應用場景:
- 資源清理:在對象被垃圾回收時,執行一些資源清理工作,如關閉文件句柄、釋放資源等。
6. 如何判斷一個對象是否被垃圾回收了?
問題:如何判斷一個對象是否被垃圾回收了?
答案:
- 可以使用
PhantomReference
來判斷對象是否被垃圾回收。當對象被垃圾回收時,PhantomReference
的get
方法會返回null
。 - 可以將
PhantomReference
添加到ReferenceQueue
中,當對象被垃圾回收時,ReferenceQueue
會收到通知。
7. 引用傳遞是按值傳遞還是按引用傳遞?
問題:Java中的引用傳遞是按值傳遞還是按引用傳遞?
答案:
- 按值傳遞:Java中的參數傳遞是按值傳遞的。對于基本類型,傳遞的是值的副本;對于引用類型,傳遞的是引用的副本。
- 按引用傳遞的副本:傳遞的是對象引用的副本,而不是對象本身。因此,可以通過引用修改對象的狀態,但不能改變引用本身。
8. 如何避免內存泄漏?
問題:如何避免內存泄漏?
答案:
- 及時釋放引用:不再使用的對象要及時釋放引用,避免長時間持有無用對象的引用。
- 使用弱引用:在緩存和監聽器等場景中,使用弱引用來避免內存泄漏。
- 靜態變量謹慎使用:靜態變量的生命周期與類相同,容易導致內存泄漏。
- 關閉資源:及時關閉文件句柄、數據庫連接等資源,避免資源泄漏。
9. 什么是引用計數法?Java的垃圾回收器是否使用引用計數法?
問題:什么是引用計數法?Java的垃圾回收器是否使用引用計數法?
答案:
- 引用計數法:每個對象都有一個引用計數器,每當有一個地方引用它時,計數器加1;當引用失效時,計數器減1。當計數器為0時,對象可以被回收。
- Java的垃圾回收器:Java的垃圾回收器不使用引用計數法,而是使用可達性分析算法(Reachability Analysis)。通過從根節點(如棧幀中的局部變量表、方法區中的類靜態屬性)出發,遍歷所有可達對象,未被遍歷到的對象被視為垃圾,可以被回收。
10. 什么是可達性分析算法?
問題:什么是可達性分析算法?
答案:
- 可達性分析算法:從一系列稱為“GC Roots”的對象開始,向下搜索,走過的路徑稱為引用鏈。當一個對象到GC Roots沒有任何引用鏈相連時,證明此對象是不可達的,可以被垃圾回收。
- GC Roots:包括棧幀中的局部變量表、方法區中的類靜態屬性、本地方法棧中的JNI引用等。
11. 什么是弱引用表?它在垃圾回收中的作用是什么?
問題:什么是弱引用表?它在垃圾回收中的作用是什么?
答案:
- 弱引用表:垃圾回收器在進行垃圾回收時,會維護一個弱引用表,記錄所有弱引用的對象。
- 作用:在垃圾回收過程中,垃圾回收器會檢查弱引用表中的對象,如果這些對象沒有其他強引用,就會被回收。弱引用表主要用于實現內存敏感的緩存和資源管理。
12. 如何使用 WeakHashMap
?
問題:如何使用 WeakHashMap
?
答案:
WeakHashMap
:是一個基于弱引用的哈希表,鍵是弱引用,值可以是任意引用類型。- 使用場景:適用于實現內存敏感的緩存,當鍵對象被垃圾回收時,對應的條目也會被移除。
- 示例代碼:
import java.util.WeakHashMap;public class WeakHashMapExample {public static void main(String[] args) {WeakHashMap<String, String> map = new WeakHashMap<>();String key = new String("key");map.put(key, "value");System.out.println(map.get(key)); // 輸出 "value"key = null;System.gc(); // 請求垃圾回收// 垃圾回收后,鍵對象被回收,對應的條目也被移除System.out.println(map.get("key")); // 輸出 null} }
13. 什么是引用隊列?如何使用?
問題:什么是引用隊列?如何使用?
答案:
- 引用隊列:
ReferenceQueue
是一個隊列,用于接收被垃圾回收器回收的引用對象。 - 使用場景:通常與
PhantomReference
一起使用,用于在對象被垃圾回收時收到通知。 - 示例代碼:
import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue;public class PhantomReferenceExample {public static void main(String[] args) {Object obj = new Object();ReferenceQueue<Object> queue = new ReferenceQueue<>();PhantomReference<Object> phantomRef = new PhantomReference<>(obj, queue);obj = null;System.gc(); // 請求垃圾回收// 檢查引用隊列PhantomReference<?> ref = (PhantomReference<?>) queue.poll();if (ref != null) {System.out.println("對象已被垃圾回收");}} }
14. 什么是引用逃逸?如何避免?
問題:什么是引用逃逸?如何避免?
答案:
- 引用逃逸:在對象構造過程中,對象的引用被外部訪問,導致對象在未完全構造完成的情況下被使用。
- 避免方法:
- 私有化構造函數:將構造函數設為私有,通過工廠方法創建對象。
- 避免在構造函數中傳遞引用:不要在構造函數中將對象的引用傳遞給外部方法。
- 使用
final
修飾符:將對象的屬性設為final
,確保對象的不可變性。
15. 什么是引用透明性?Java中的引用是否透明?
問題:什么是引用透明性?Java中的引用是否透明?
答案:
- 引用透明性:在一個表達式中,如果可以用一個值替換另一個值而不改變程序的行為,那么這個表達式就是引用透明的。
- Java中的引用:Java中的引用不是完全透明的,因為引用的賦值和傳遞可能會改變對象的狀態。但是,對于不可變對象(如
String
),引用是透明的。