常見的JAVA虛擬機HotSpot虛擬機運行時數據庫由5部分構成:方法區,堆,虛擬機棧,本地方法棧,程序計數器。下面列舉各個部分可能出現的異常及其出現緣由。數據庫
1.方法區存放的已被虛擬機加載的類型信息,常量、靜態變量、即時編譯器編譯後的代碼緩存等數據。可能出現的異常有OutOfMemoryError,緣由多是建立了過多的常量(不太可能,由於自JDK7起,本來存放在永久代中的字符串常量池被移至Java堆中,故JDK7前的運行池常量溢出報錯由OOM:PerGem space變爲了OOM:Java heap space),生成大量動態類,大量JSP或動態產生JSP文件的應用(JSP第一次運行時須要編譯爲Java類)、使用了CGLib字節碼加強和動態語言,基於OSGi的應用(即便是同一個類,被不一樣的加載器加載也會視爲不一樣的類)等。緩存
2.堆是虛擬機所管理的內存中最大的一塊,惟一目的是存放對象實例。可能出現的異常有OutOfMemoryError,緣由是Java堆中沒有內存可以完成實例分配,而且堆也沒法再擴展。解決辦法:使用參數-Xmx提升最大堆容量。檢查是否存在某些對象生命週期過長、持有狀態時間過長、存儲結構設計不合理等狀況。spa
3.虛擬機棧和本地方法棧發揮的做用很是類似,在HotSpot虛擬機二者合二爲一,存儲局部變量表、操做數棧、動態鏈接、方法出口等信息。若是線程請求的棧深度大於虛擬機所容許的最大深度,將拋出StackOverflowError異常;出現StackOverflowError的緣由可能時本地變量過多或者棧內存容量過小,解決辦法:使用-Xss提升棧容量最小值。線程
若是虛擬機的棧內存容許動態擴展,當擴展棧容量沒法申請到足夠的內存時,將拋出OutOfMemoryError異常(HotSpot虛擬機不支持擴展,因此只有建立線程申請內存時就由於沒法得到足夠的內存而出現OutOfMemoryError異常)。出現的緣由多是建立的線程過多,解決辦法:減小線程數量,減小最大堆和減小棧容量換取更多的線程(總的內存有限,減去堆和方法區的容量,剩餘的內存會多些)。設計
4.程序計數器不會出現異常。對象
以上是經過周志明老師的《深刻理解Java虛擬機》獲得的小結。生命週期