JVM內存模型圖解(包含堆棧方法區例子和圖解)

下圖是完整的虛擬機模型

在這裏插入圖片描述

我們主要是瞭解三個

1. 堆區(heap ):

存儲的全部是對象,每個對象都包含一個與之對應的class的信息。

jvm只有一個堆區(heap)被所有線程共享,堆中不存放基本類型和對象引用,只存放對象本身

2. 棧區(stack):

基本類型變量區、執行環境上下文、操作指令區

每一個線程包含一個stack區,只保存基本數據類型的對象和自定義對象的引用(不是對象),對象都存放在共享堆中;

每個棧中的數據(原始類型和對象引用)都是私有的,其他棧不能訪問。

3. 方法區(meathod area):

又叫靜態區,跟堆一樣,被所有的線程共享。方法區包含所有的class和static變量。

方法區中包含的都是在整個程序中永遠唯一的元素,如class,static變量。

運行時常量池都分配在 Java 虛擬機的方法區之中
另外兩個知道就行了:
本地方法棧(Native Method Stack)
當JVM在執行Native方法時,會在此區域中創建一個棧幀來存放方法的各種信息,比如返回值,局部變量表和各種對象引用等,方法開始執行前就先創建棧幀入棧,執行完後就出棧。

程序計數器(Program Counter Register)
佔用很小的一片區域,我們知道JVM執行代碼是一行一行執行字節碼,所以需要一個計數器來記錄當前執行的行數。
在這裏插入圖片描述
上圖引用的是 '‘斯文流氓騷剛’'的博客圖片

1.1堆詳情圖解

堆裏面分爲年輕代老年代

年輕代默認佔1/3(Eden默認8/10 , from默認1/10 , to默認 1/10)
老年代默認佔2/3

在這裏插入圖片描述

minor gc :對年輕代的垃圾回收稱作初級回收 , 輕GC

Full GC 是發生在老年代的垃圾收集動作,所採用的是標記-清除算法

(滿了以後自動執行GC , 瞭解GC看我以前博客:
https://blog.csdn.net/qq_42795915/article/details/84202836)

new 的對象先進入Eden 以後經過minor gc計算後放入 from , from 再進行minor gc放入to , 再放入from , 直到對象年齡達到15,若還是有引用對象,再放入老年代

老年代滿了以後會進行一次Full GC的操作 , 如果gc以後還是滿的 , 甚至溢出 , 就會產生堆內存溢出錯誤


舉個堆棧方法區的栗子


public class MainMemory {
    
        int id;
        String name;
        int size;
        Data data;
    
        void store() {
            System.out.println("執行存儲中,存儲數據類型:" + data.type);
        }
    
        void release() {
            System.out.println("釋放內存中");
        }
    
        // 構造方法
        MainMemory(){
    
        }
    
        public static void main(String [] args) {
            MainMemory memory = new MainMemory();   //  創建一個對象
            memory.id=1;
            memory.name = "test";
            memory.size = 1024;
    
            Data data = new Data();
            data.type = "字符串";
            memory.data = data;
            
            memory.store();
            memory.release();
        }
    }
    
    class Data{
        public String type;        //這裏不能使用私有類
    }

過程:

  1. java MainMemory,系統收到指令,啓動一個java虛擬機進程

  2. 進程首先從classpath中找到MainMemory.class文件,讀取該文件的二進制數據,就是將類信息存放到運行時數據去的方法區中,整個過程是類加載過程,將其加載到方法區中

  3. Java虛擬機定位到方法區中MainMemory類的main()方法的字節碼,執行了方法,會分配一個棧幀。

  4. 創建一個實例對象,也就是在堆區分配一個對象的內存,給對象屬性賦值

  5. 創建一個Data類對象,先加載該類,然後再分配對象內存,再給該對象賦值

  6. 調用store()方法,分配棧幀

  7. 調用release()方法,分配棧幀

圖解:
在這裏插入圖片描述
以上例子來自 '哈K '的博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章