以下內容整理自互聯網,僅用于個人學習
轉載自http://www.cnblogs.com/yumo/p/4909617.html
Throwable
Throwable類是所有錯誤或異常的超類。只有當對象是此類或其子類之一的實例時,才能通過JVM或者是通過throw語句拋出;另外catch子句中的參數類型也必須是該類型。
Throwable包含兩個子類: **Error **和 **Exception **。它們通常用于指示發生了異常情況。
Throwable類和子類的兩個構造方法:
- 不帶參數
- 帶有String參數
Throwable包含了其線程創建時線程執行堆棧的快照,它提供了printStackTrace()等接口用于獲取堆棧跟蹤數據等信息。
Exception
Exception及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件。對于可以恢復的條件使用“被檢查異常”(Exception的子類中除了RuntimeException之外的其它子類),對于程序錯誤使用“運行時異?!薄?/strong>
RuntimeException
RuntimeException是那些可能在 Java 虛擬機正常運行期間拋出的異常的超類。 編譯器不會檢查RuntimeException異常。 例如,除數為零時,拋出ArithmeticException異常。當程序中可能出現這類異常時,還是會編譯通過。雖然Java編譯器不會檢查運行時異常,但是我們也可以通過throws進行聲明拋出,也可以通過try-catch對它進行捕獲處理。
Error
和Exception一樣, Error也是Throwable的子類。 它用于指示合理的應用程序不應該試圖捕獲的嚴重問題,大多數這樣的錯誤都是異常條件。
和RuntimeException一樣, 編譯器也不會檢查Error。
Java將可拋出(Throwable)的結構分為三種類型: 被檢查的異常(Checked Exception),運行時異常(RuntimeException)和錯誤(Error)。
- 運行時異常
定義 : RuntimeException及其子類都被稱為運行時異常。
ArithmeticException:當出現異常的運算條件時,拋出此異常。例如,一個整數“除以零”時,拋出此類的一個實例。
ClassCastException:當試圖將對象強制轉換為不是實例的子類時,拋出該異常。例如:Object x = new Integer(0);
LllegalArgumentException:拋出的異常表明向方法傳遞了一個不合法或不正確的參數。
IllegalStateException:在非法或不適當的時間調用方法時產生的信號。換句話說,即Java環境或Java應用程序沒有處于請求操作所要求的適當狀態下。
IndexOutOfBoundsException:指示某排序索引(例如對數組、字符串或向量的排序)超出范圍時拋出。 應用程序可以為這個類創建子類,以指示類似的異常。
NoSuchElementException:由Enumeration的nextElement方法拋出,表明枚舉中沒有更多的元素。
NullPointerException:當應用程序試圖在需要對象的地方使用null時,拋出該異常。這種情況包括:
調用null對象的實例方法。
訪問或修改null對象的字段。
將null作為一個數組,獲得其長度。
將null作為一個數組,訪問或修改其時間片。
將null作為Throwable值拋出。
應用程序應該拋出該類的實例,指示其他對null對象的非法使用。
- 被檢查的異常
定義 : Exception類本身,以及Exception的子類中除了"運行時異常"之外的其它子類都屬于被檢查異常。
特點 : Java編譯器會檢查它。 此類異常,要么通過throws進行聲明拋出,要么通過try-catch進行捕獲處理,否則不能通過編譯。例如,CloneNotSupportedException就屬于被檢查異常。當通過clone()接口去克隆一個對象,而該對象對應的類沒有實現Cloneable接口,就會拋出CloneNotSupportedException異常。 被檢查異常通常都是可以恢復的。
- 錯誤
定義 : Error類及其子類。
特點 : 和運行時異常一樣,編譯器也不會對錯誤進行檢查。 當資源不足、約束失敗、或是其它程序無法繼續運行的條件發生時,就產生錯誤。程序本身無法修復這些錯誤的。例如,VirtualMachineError就屬于錯誤。
OOM
- OutOfMemoryError異常
除了程序計數器外,虛擬機內存的其他幾個運行時區域都有發生OutOfMemoryError(OOM)異常的可能,
Java Heap 溢出
一般的異常信息:java.lang.OutOfMemoryError:Java heap spacess
java堆用于存儲對象實例,我們只要不斷的創建對象,并且保證GC Roots到對象之間有可達路徑來避免垃圾回收機制清除這些對象,就會在對象數量達到最大堆容量限制后產生內存溢出異常。
出現這種異常,一般手段是先通過內存映像分析工具(如Eclipse Memory Analyzer)對dump出來的堆轉存快照進行分析,重點是確認內存中的對象是否是必要的,先分清是因為內存泄漏(Memory Leak)還是內存溢出(Memory Overflow)。
如果是內存泄漏,可進一步通過工具查看泄漏對象到GC Roots的引用鏈。于是就能找到泄漏對象時通過怎樣的路徑與GC Roots相關聯并導致垃圾收集器無法自動回收。
如果不存在泄漏,那就應該檢查虛擬機的參數(-Xmx與-Xms)的設置是否適當。
- 虛擬機棧和本地方法棧溢出
如果線程請求的棧深度大于虛擬機所允許的最大深度,將拋出StackOverflowError異常。
如果虛擬機在擴展棧時無法申請到足夠的內存空間,則拋出OutOfMemoryError異常
這里需要注意當棧的大小越大可分配的線程數就越少。
- 運行時常量池溢出
異常信息:java.lang.OutOfMemoryError:PermGen space
如果要向運行時常量池中添加內容,最簡單的做法就是使用String.intern()這個Native方法。該方法的作用是:如果池中已經包含一個等于此String的字符串,則返回代表池中這個字符串的String對象;否則,將此String對象包含的字符串添加到常量池中,并且返回此String對象的引用。由于常量池分配在方法區內,我們可以通過-XX:PermSize和-XX:MaxPermSize限制方法區的大小,從而間接限制其中常量池的容量。
- 方法區溢出
方法區用于存放Class的相關信息,如類名、訪問修飾符、常量池、字段描述、方法描述等。
異常信息:java.lang.OutOfMemoryError:PermGen space
方法區溢出也是一種常見的內存溢出異常,一個類如果要被垃圾收集器回收,判定條件是很苛刻的。在經常動態生成大量Class的應用中,要特別注意這點。
SOF
程序中一旦出現死循環或者是大量的遞歸調用,在不斷的壓棧過程中,造成棧容量超過默認大小而導致溢出。
棧溢出的原因:
- 遞歸調用
- 大量循環或死循環
- 全局變量是否過多
- 數組、List、map數據過