1. 程式人生 > >JVM之基本結構

JVM之基本結構

rac 判斷 .com sys count define inf wid 正在

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之基本結構