JVM之基本結構
1. Java虛擬機的架構
1.1 Java的NIO庫允許Java程序使用直接內存,訪問直接內存的速度優於Java堆。出於性能的考慮,讀寫頻繁的場合會考慮使用直接內存。
1.2 本地方法棧和Java棧非常類似,最大的不同在於Java棧用於Java方法的調用,而本地方法棧用於本地方法的調用。
1.3 PC 寄存器: Program Counter寄存器
1.4 在任意時刻,一個Java線程總是在執行一個方法。如果這個方法不是本地方法,PC寄存器就會指向當前正在被執行的指令;如果這個方法是本地方法,PC寄存器的值是undefined。
2.Java堆
2.1 結構:根據垃圾回收機制的不同,Java堆可能有不同的結構。最常見的一種結構是將Java堆分為新生代和老年代。
2.2 流程:
在絕大多數情況下,對象首先會分配到eden區,在一次新生代回收後,如果對象還存活,會進入s0或則s1區;之後,每經歷一次新生代回收,如果對象還存活,則年齡加1。年齡達到一定條件後,會被認為是老年對象,進入老年代。
3.Java棧
3.1棧幀出入棧【函數調用】過程
3.1.1 出棧順序:先入後出
3.1.2 每次函數調用的數據都是通過Java棧傳遞的。
3.1.3 Java棧中保存的主要內容是是棧幀。[棧幀中保存著當前函數的局部變量、中間運算結果等數據]。
3.2 Java棧基本構架
3.2.1 棧幀至少包含局部變量表、操作數棧和幀數據區。
3.4 當棧空間不足時,函數調用無法繼續,系統會拋出StackOverflowError棧溢出錯誤。【可以通過-Xss設置線程的最大棧空間】
3.5 StackOverflowError演示【遞歸死循環】
package com.blueStarWei.jvm; public class StackOverflowError { private static int count = 0; public static void main(String[] args) {try{ recursion(); }catch(Throwable e){ System.out.println("deep of calling : "+count); e.printStackTrace(); } } public static void recursion(){ count++; recursion(); } }
3.5.1 日誌輸出
//根據-Xss配置的參數不同,被調用的次數會不同 deep of calling : 31661 java.lang.StackOverflowError at com.blueStarWei.jvm.StackOverflowError.recursion(StackOverflowError.java:18)
4. 局部變量表
4.1 槽位復用
4.1.1 含義:如果局部變量A超出其作用域,那麽在其作用域之後的局部變量B會復用A的槽位。
4.1.2 優點: 節省資源
4.1.3 註意:如果A作用域之後沒有新的變量,A不會從局部變量表中移除【可以使用-XX:+PrintGC查看GC信息,判斷是否觸發GC】
//局部變量a仍然存在於局部變量表中,不會觸發GC public void localGC1(){ { byte[] a = new byte[6*1024*1024]; } System.gc(); } //局部變量a的槽位已經被局部變量b復用,觸發GC[回收局部變量a] public void localGC2(){ { byte[] a = new byte[6*1024*1024]; } int b = 0; System.gc(); }
JVM之基本結構