目錄
- 一、ch 2 exception和error
- 二、ch4| 強引用、軟引用、弱引用、幻象引用
一、ch 2 exception和error
1、知識概要
理解 Throwable、Exception、Error 的設計和分類
- 理解 Java 語言中操作 Throwable 的元素和實踐。掌握最基本的語法是必須的,如 try-catch-finally 塊,throw、throws 關鍵字等。
- 生吞異常(捕獲異常最差的處理方式)
- 自定義異常:定義成checked exception
(但:①大多數情況并不能恢復程序②不兼容functional編程)
,并避免包含敏感信息
2、案例分析
- 輸入以下代碼
public class test {
public static void main(String[] args) {
try {
Class.forName("src.HelloWorld");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
結果
彈出exception
- 說明找不到類,將
src.HelloWorld
替換成test321.HelloWorld
public class test {
public static void main(String[] args) {
try {
Class.forName("tsst321.HelloWorld");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
結果說明能成功運行
3、問題提出與解決
- 問題一:NoClassDefFoundError 和 ClassNotFoundException 有什么區別?
- 問題一解決:
NoClassDefFoundError是一個錯誤(Error),而ClassNOtFoundException是一個異常,在Java中錯誤和異常是有區別的,我們可以從異常中恢復程序但卻不應該嘗試從錯誤中恢復程序。
加載時從外存儲器找不到需要的class就出現ClassNotFoundException
連接時從內存找不到需要的class就出現NoClassDefFoundError
- classnotfoundexception發生在裝入階段
- 如果這個類在類路徑中沒有被找到——確保所需的類連同它依賴的包存在于類路徑中
- 當一個類已經某個類加載器加載到內存中了,此時另一個類加載器又嘗試著動態地從同一個包中加載這個類——選擇catch這個衣長然后采取補救措施
- NoClassDefFoundError: 發生在運行階段。(當目前執行的類已經編譯,但是找不到它的定義時,編譯時能找到,但是運行時找不到)
- 查找那些在開發期間存在于類路徑下但在運行期間卻不在類路徑下的類
- 查找那些在開發期間存在于類路徑下但在運行期間卻不在類路徑下的類
4、參考資料
- 第2講 | Exception和Error有什么區別?
- java.lang.ClassNotFoundException與java.lang.NoClassDefFoundError的區別 -xingoo - 博客園
ch4 強引用、軟引用、弱引用、幻象引用
1、內容概要
① 強引用(在程序代碼中普遍存在的)
- 特點:
Object obj = new Object()
中的obj
就是強引用;通過關鍵字new
創建的對象所關聯的引用就是強引用。 - 當JVM內存空間不足,JVM寧愿拋出OutOfMemoryError運行時錯誤(OOM),使程序異常終止,也不會靠隨意回收具有強引用的“存活”對象來解決內存不足的問題。
② 軟引用(描述一些有用但并不是必需的對象)
- 特點:通過
SoftReference
類實現,在Java中用java.lang.ref.SoftReference
來表示。 軟引用的生命周期比強引用短一些。 - JVM 會確保在拋出 OutOfMemoryError 之前,清理軟引用指向的對象。
- 應用場景:軟引用通常用來實現內存敏感的緩存。如果還有空閑內存,就可以暫時保留緩存,當內存不足時清理掉,這樣就保證了使用緩存的同時,不會耗盡內存。
③ 弱引用(描述非必需對象)
- 特點:通過
WeakReference
類實現,在java中,用·java.lang.ref.WeakReference·類來表示。弱引用的生命周期比軟引用短。 - 一旦發現了具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存。
- 應用場景:弱應用同樣可用于內存敏感的緩存。
④ 幻想引用
- 特點:虛引用也叫幻象引用,通過
PhantomReference
類來實現,在java中用java.lang.ref.PhantomReference
類表示無法通過虛引用訪問對象的任何屬性或函數。 - 虛引用必須和引用隊列 (ReferenceQueue)聯合使用。當垃圾回收器準備回收一個對象時,如果發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之關聯的引用隊列中。
ReferenceQueue queue = new ReferenceQueue ();
PhantomReference pr = new PhantomReference (object, queue);
程序可以通過判斷引用隊列中是否已經加入了虛引用,來了解被引用的對象是否將要被垃圾回收。
- 應用場景:可用來跟蹤對象被垃圾回收器回收的活動,當一個虛引用關聯的對象被垃圾收集器回收之前會收到一條系統通知。
2、示例
- 軟引用
import java.lang.ref.SoftReference;
public class reference {
public static void main(String[] args) {
SoftReference<String> sr = new SoftReference<String>(new String("hello"));
System.out.println(sr.get());
}
}
- 弱引用
import java.lang.ref.WeakReference;
public class reference {
public static void main(String[] args) {
WeakReference<String> sr = new WeakReference<String>(new String("hello"));
System.out.println(sr.get());
System.gc(); //通知JVM的gc進行垃圾回收
System.out.println(sr.get());
}
}
- 虛引用
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class reference {
public static void main(String[] args) {
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
System.out.println(pr.get());
}
}
3、問題提出與解決
- 問題一:什么是可達性?
- 問題一解決:可達性分析其實是用來判定對象是否存活的。如果不可達,則證明該對象不可用,說明其可以被回收。
- 問題二:如何判斷是否需要被回收?
- 問題二解決:
Strong Reference : 只有在引用對象root不可達的情況下才會標識為可回收,垃圾回收才可能進行回收
Soft Reference : 無論其引用的對象是否root可達,在響應內存需要時,由垃圾回收判斷是否需要回收。
Weak Reference :用來描述非必需對象。即使在root算法中 其引用的對象root可達到,只能生存到下一次垃圾回收之前。
Phantom Reference :無法通過虛引用獲得一個對象的實例,設置虛引用的目的就是能在這個對象被收集器回收時收到一個系統通知。
- 問題三:除了可達性算法,還有什么方法來判斷對象是否存活?
- 問題三解決:finalize()方法
- 進行兩次標記
- 只要重新與引用鏈上的任何的一個對象建立關聯,譬如把自己賦值給某個類變量或對象的成員變量,那在第二次標記時它將移除出“即將回收”的集合。