深入理解java虛擬機學習筆記(一)java虛擬機運行時數據區域

java虛擬機運行時數據區域

 

java虛擬機內存管理圖

java虛擬機運行時數據區分爲線程共享區和線程獨佔區。

其中線程共享區中包括方法區和java堆;線程獨佔區包括虛擬機棧、本地方法棧、程序計數器。

下面對每部分分別進行解釋:

一、程序計數器:

    1.程序計數器是一塊較小的內存空間,它可以看作是當前線程所執行的字節碼的行號指示器。

    2.程序計數器處於線程獨佔區。

    3.如果線程執行的是java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址。如果正在執行的是    native方法,這個計算器的值爲undefined。

    4.此區域是唯一一個在java虛擬機規範中沒有規定任何OutOfMemoryError(內存溢出)情況的區域。

二、java虛擬機棧:

    1.虛擬機棧描述的是java方法執行的動態內存模型。

    2.棧幀:每個方法執行,都會創建一個棧幀,伴隨着方法從創建到執行完成。

    用於存儲局部變量表,操作數棧,動態鏈接,方法出口燈等。

    3.局部變量表:存放編譯期可知的各種基本數據類型,引用類型,returnAddress類型。

    局部變量表所需要的內存空間在編譯期完成分配,當進入一個方法時,這個方法需要在幀分配多少內存是固定的,在方法運行期間是不會改變局部變量表的大小。

    4.大小:虛擬機棧大小有限,如果棧滿了,方法仍然調用,那麼會出現棧內存溢出,StackOverflowError。

    如果不指定棧內存大小,方法一直調用,一直去申請棧內存,棧滿了會拋出內存溢出,OutOfMemoryError。

例如:

public class StackTest {

    private void test(){
        System.out.println("方法執行..");
        test();
    }
    public static void main(String[] args){
        new StackTest().test();
    }

}

三、本地方法棧:

    本地方法棧與虛擬機非常相似。

    區別:虛擬機棧爲虛擬機執行java方法服務;本地方法棧爲虛擬機執行native方法服務。

四、Java堆:

    存放對象實例;

    垃圾收集器管理的主要區域;

    新生代,老年代,Eden空間;

    如果內存溢出,會拋出OutOfMemoryError異常;

    通過-Xmx、-Xms控制大小。 

五、方法區:

    存儲虛擬機加載的類信息,常量,靜態變量,即時編譯器編譯後的代碼等數據。類信息包括類的版本、字段、方法、接口等。

    方法區和永久代。這兩者並不等價。

    垃圾回收在方法區的行爲。垃圾回收主要在java堆中,方法區也有比如常量池。

    異常的定義。申請失敗會拋出OutOfMemoryError異常

六、運行時常量池:

    運行時常量池是方法區的一部分。存放的是編譯器生成的各種字面量和符號引用。

public static void main(String[] args){

    String s1 = "abc";//"abc"在常量池中存儲
    String s2 = "abc";
    System.out.println(s1==s2);//true
    String s3 = new String("abc");//new創建的對象在堆中存儲
    System.out.println(s1==s3);//flase
    //intern方法把值放到常量池中
    System.out.println(s1==s3.intern());//true
}

 

    申請內存失敗會拋出OutOfMemoryError異常。

七、直接內存:

    直接內存不是虛擬機運行時數據區的一部分,也不是java虛擬機規範中定義的內存區域。但是這部分內存被頻繁的使用,而且可能導致OutOfMemoryError異常。

 

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