1. 程式人生 > >第二章Java記憶體區域與記憶體溢位異常

第二章Java記憶體區域與記憶體溢位異常

JVM記憶體模型及特徵:

堆:
	1.JVM管理記憶體中最大的一塊,被所有執行緒共享
	2.唯一目的是存放物件例項和陣列
	3.垃圾蒐集器管理的主要區域
	4.可擴充套件,通過-Xmx和-Xms來控制
	5.如果在堆中沒有記憶體完成例項分配,並且堆也無法再擴充套件時,將會丟擲OutOfMemoryError異常
虛擬機器棧:
	1.執行緒私有  
	2.區域性變量表所需的記憶體空間在編譯期間完成分配
	3.該區域規定了兩種異常狀況:
		a.執行緒請求的棧深度大於虛擬機器所允許的棧深度,將丟擲StackOverflowError(棧溢位)異常
		b.如果虛擬機器棧可以動態擴充套件(大部分允許,也允許固定長度的虛擬機器棧),如果擴充套件時申請不到足夠的記憶體,就會丟擲OutOfMemoryError(記憶體不足)異常
	4.虛擬機器棧為虛擬機器執行java方法服務
方法區:
	1.各個執行緒間共享,用於儲存已被虛擬機器載入的類資訊,常量,靜態變數,即時編譯器編譯的程式碼等
	2.這區域的記憶體回收目標主要是針對常量池的回收和對型別的解除安裝
	3.會丟擲OutOfMemoryError異常
	4.Class檔案中,除了有類的版本,欄位,方法,介面等描述資訊外,還有一項資訊是常量池.執行時常量池是方法區的一部分,用於存放編譯器生成的各種字面量和符號引用
本地方法棧:
	1.本地方法棧為虛擬機器執行Native方法服務
	2.本地方法棧會丟擲StackOverflowError和OutOfMemoryError異常
程式計數器:
	1.java虛擬機器的多執行緒是通過執行緒輪流切換並分配處理器執行時間的方式實現的,為了執行緒切換後能恢復到正確的執行位置,每個執行緒都需要有一個獨立的程式計數器,各執行緒間計數器互不影響,獨立儲存,我們稱這類記憶體區域為"執行緒私有"的記憶體
	2.執行緒私有

堆中記憶體分配方式:

指標碰撞:

假設堆中記憶體是絕對規整的,所有用過的記憶體放在一邊,空閒的記憶體放在另一邊.在使用Serial,ParNew等帶Compact過程的蒐集器時,系統採用的分配演算法是指標碰撞

空閒列表:

虛擬機器維護一個列表,記錄哪些記憶體是可用的.使用CMS這種基於Mark-Sweep演算法的蒐集器時,通常採用空閒列表

常見問題:

1.為什麼要給每個執行緒開闢一個獨立的記憶體空間

java虛擬機器的多執行緒是通過執行緒輪流切換並分配處理器執行時間的方式實現的,為了執行緒切換後能恢復到正確的執行位置,每個執行緒都需要有一個獨立的程式計數器,各執行緒間計數器互不影響,獨立儲存,我們稱這類記憶體區域為"執行緒私有"的記憶體