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堆分爲新生代、老年代
			新生代(New generation 或 Young generation)
				結構:Eden空間、From Survivor空間、To Survivor空間
				特點:新生代中大部分的對象是“朝生夕死”的,每次垃圾收集時都發現有大批對象死去,只有少量存活
			老年代(Old generation 或 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 的場景中都需要虛擬機具備類卸載功能,以保證方法區不會溢出。

		

發佈了298 篇原創文章 · 獲贊 56 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章