1. 程式人生 > >【夾娃系列】java面試基礎知識儲備(¥2)——JVM記憶體劃分和記憶體溢位異常的原因和解決方法

【夾娃系列】java面試基礎知識儲備(¥2)——JVM記憶體劃分和記憶體溢位異常的原因和解決方法

JVM記憶體劃分和記憶體溢位

JVM記憶體劃分

在這裡插入圖片描述
堆:存放物件例項,被所有的執行緒共享的一塊區域。垃圾收集器管理的主要區域。
方法區:儲存虛擬機器載入的類資訊,常量,靜態變數,編譯後的程式碼等資料。有時被成為永久代(HotSpot虛擬機器上這麼稱謂)
虛擬機器棧:每一個方法在執行時都會產建立一個棧幀,用來儲存區域性變量表,運算元棧,動態連結,方法出口等資訊。區域性變量表中存放了編譯期就知道的各種基本資料型別,物件的引用等。常見的錯誤為:StackOverflowError
本地方法棧:為虛擬機器使用到的本地方法服務。很多虛擬機器中將虛擬機器棧和本地方法棧合二為一。其作用和虛擬機器棧是一樣的。
程式計數器:佔用比較小 的空間。類似於一般作業系統中的pc計數器,通過改變計數器的值,來執行下一條位元組碼的指令。相當於位元組碼的行號指示器,進行分支跳轉或者迴圈,異常處理等操作。

記憶體溢位的異常和解決辦法

1.Java.lang.OutOfMemoryError: PermGen space
錯誤:永久代區域發生了記憶體溢位,發生在方法區!
原因:一是方法區中執行時常量池溢位,就是在執行過程中產生了大量的常量比如i++無限迴圈的產生。二是呼叫的類太多,導致方法區記憶體溢位。
解決:手動設定MaxPermSize大小(在編譯器中可以設定)

2.java.lang.OutOfMemoryError: Java heap space
錯誤:java堆溢位。
原因:直接原因是達到了最大堆的容量。導致錯誤的深層次原因是,可能某些物件的生命期過長或者可能是一直產生物件,並且GC無法回收,引起的記憶體洩漏。
解決:手動將最大堆的size設定大一些,一般為實體記憶體的25%,不超過80%。減少物件持有時間過長的現象。
3.java.lang.StackOverflowError
錯誤:虛擬機器棧和本地方法棧溢位。
原因:執行緒申請的棧的深度大於虛擬機器允許的棧的深度;棧擴充套件時申請記憶體失敗或丟擲記憶體溢位而不是棧溢位。
解決:檢查是否遞迴呼叫沒有出口,或者棧幀過大或者本地變數太多。一般上程式碼層面的問題較為常見。如果程式碼層面,實屬是記憶體不夠引起的,減少執行緒或者使用更高配置的電腦(64位,128位等)。實在沒法了,可以減小最大堆size和最大方法區size。因為最大堆,最大方法區容量,虛擬機器棧,本地方法棧共同瓜分了同一執行緒的記憶體,比如windows是2G.
4.java.lang.OutOfMemoryError
解決:這個同樣是記憶體溢位,但並沒有提示什麼具體錯誤。就有可能是本地直接記憶體溢位。可以手動設定本地直接記憶體的大小。