Java內存分析 --- 虛擬機運行時數據區

Java內存分析:虛擬機運行時數據區算法

1)程序計數器(Program Counter Register):能夠看作當前線程所執行的字節碼的行號指示器
	工做:經過改變這個計數器的值來選取下一條須要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都依賴這個計數器完成。
	說明:程序計數器是線程私有的。每條線程都須要有一個獨立的程序計數器,各條線程間的計數器互不影響,獨立儲存。
	舉例:若是線程正在執行的是一個Java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令地址;若是正在執行的是native方法,這個計數器值則爲空。

2)Java虛擬機棧:描述的是Java方法執行的內存模型。
	工做:每一個方法在執行的同時都會建立一個棧幀(Stack Frame)用於儲存局部變量表、操做數棧、動態連接、方法出口等信息,每個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中入棧道出棧的過程。
	說明:	1)Java虛擬機棧是線程私有的,它的生命週期與線程相同。
			2)通常人們所說的「棧」就是指虛擬機棧,或者指虛擬機棧中局部變量表部分
				局部變量表存放了編譯期可知的各類基本數據類型(boolean、byte、char、int..)、對象引用等

	異常:虛擬機棧中規定了兩種異常情況:
		1)若是線程請求的棧深度大於虛擬機所容許的深度,將拋出StackOverflowError異常;
		2)若是虛擬機棧能夠動態擴展(當前大部分的Java虛擬機均可以動態擴展),若是擴展時沒法申請到足夠的內存,就會拋出OutOfMemoryError異常

3)本地方法棧(Native Method Stack):爲虛擬機使用到的Native方法服務。
	說明:與虛擬機棧的區別:虛擬機棧爲虛擬機執行Java方法(也就是字節碼)服務,而本地方法棧則爲虛擬機使用到的Native方法服務。
		Sun HotSpot虛擬機直接就把本地方法棧和虛擬機棧合二爲一。


	異常:與虛擬機棧中規定的異常相同。
	
4)Java堆:是被全部線程共享的一塊內存區域,在虛擬機啓動時建立。惟一的目的就是存放對象實例
	
	如今收集器基本都採用分代收集算法
	
	Java堆分爲新生代、老年代
		新生代(Young generation)
			結構:Eden空間、From Survivor空間、To Survivor空間
			特色:新生代中大部分的對象是「朝生夕死」的,每次垃圾收集時都發現有大批對象死去,只有少許存活
		老年代(Tenured generation)
			特色:老年代中的對象存活率高、沒有額外空間對它進行分配擔保。
	
	注:新生代GC(Minor GC)、老年代GC(Full GC、Major GC)
	
5)方法區(永久代:Permanent Generation):用於儲存已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。
	說明:	1)與Java堆同樣,方法區是各個線程共享的內存區域。
			2)Java虛擬機規範把方法區描述爲堆的一個邏輯部分,可是它卻有一個別名叫作 Non-Heap(非堆)

	運行時常量池:是方法區的一部分
	
	方法區的回收:
		主要回收:廢棄的常量、無用的類
		
		廢棄常量:沒有任何引用關聯着的常量即廢棄常量。
		無用的類:同時知足如下3個條件的類
			1)該類全部的實例都已經被回收,也就是說Java堆中不存在該類的任何引用。
			2)加載該類的ClassLoader已經被回收
			3)該類對應的Class對象沒有再任何地方被引用,沒法在任何地方經過反射訪問該類的方法。
		注:知足條件的類是否會被回收,由虛擬機設定:由 -Xnoclassgc 參數進行控制。
		
		重要:在大量使用反射、動態代理(jdk動態代理、cglib動態代理等)、動態生成jsp 的場景中都須要虛擬機具有類卸載功能,以保證方法區不會溢出。
相關文章
相關標籤/搜索