JVM之基本結構

1. Java虛擬機的架構java

 

    1.0 運行時數據區:通過編譯的class文件,由ClassLoader(類加載子系統)加載後會交給執行引擎執行。在執行引擎執行過程當中,會產生一些數據,這些數據被稱爲運行時數據,存儲這些數據的內存區域稱爲運行時數據區。性能優化

    1.1 Java的NIO庫容許Java程序使用直接內存,訪問直接內存的速度優於Java堆。出於性能的考慮,讀寫頻繁的場合會考慮使用直接內存。架構

    1.2 本地方法棧和Java棧很是相似,最大的不一樣在於Java棧用於Java方法的調用,而本地方法棧用於本地方法的調用。jvm

    1.3 PC 寄存器: Program Counter寄存器,即:程序計數器,跟隨線程的啓動而建立。用於記錄當前線程重在執行的字節碼指令位置。【線程專有】函數

    1.4 在任意時刻,一個Java線程老是在執行一個方法。若是這個方法不是本地方法,PC寄存器就會指向當前正在被執行的指令;若是這個方法是本地方法,PC寄存器的值是undefined。性能

    1.5 JVM內存結構的五大區域:Java棧(虛擬機棧)、本地方法棧、PC寄存器、方法區、Java堆。其中,Java棧、本地方法棧、PC寄存器是線程專有的。優化

 

2.Java堆spa

    2.1 結構:根據垃圾回收機制的不一樣,Java堆可能有不一樣的結構。最多見的一種結構是將Java堆分爲新生代和老年代線程

   2.2 流程:3d

        在絕大多數狀況下,對象首先會分配到eden區,在一次新生代回收後,若是對象還存活,會進入s0或則s1區;以後,每經歷一次新生代回收,若是對象還存活,則年齡加1。年齡達到必定條件後,會被認爲是老年對象,進入老年代。

 

 

 3.Java棧(虛擬機棧)

  虛擬機棧是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 在JDK1.六、1.7中,方法區能夠理解爲永久區(Permanent).。JDK1.8中,永久區被完全移除,取而代之的是元數據區(堆外的直接內存

    4.2 方法區是被全部線程共用的內存空間,在JVM啓動時建立.

    4.3 運行時常量池 : 除了每一個類或接口中定義的常量,它還包含了全部對方法和字段的引用。所以當須要一個方法或字段時,JVM經過運行時常量池中的信息從內存空間中來查找其相應的實際地址。

    4.4 設置參數

參數 做用 備註
-XX:PremSize 設置永久區初始化空間  
-XX: MaxPremSize 設置永久區的最大空間 默認64MB
-XX:MaxMetaspaceSize 設置元數據區的最大空間 若是不指定大小,虛擬機會耗盡全部可用的系統內存

    4.5 垃圾收集在這個區域是比較少出現的,這區域的內存回收目標重要是針對常量池的回收和類型的卸載。

5. 局部變量表

    5.1 槽位複用

        5.1.1 含義:若是局部變量A超出其做用域,那麼在其做用域以後局部變量B複用A的槽位

        5.1.2 優勢: 節省資源

        5.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();
}

 

6.參考文獻

    6.1 《實戰Java虛擬機 - JVM故障診斷與性能優化》

相關文章
相關標籤/搜索