1. 程式人生 > >java虛擬機內存區域理解

java虛擬機內存區域理解

intern 基本 fill type 虛擬機內存區域 The 靜態變量 ava lB

java虛擬機有的區域隨著虛擬機進程的啟動而存在, 有的區域依賴用戶線程的啟動和結束而建立和銷毀。
  • 程序計數器:為了線程切換後能恢復到正確的執行位置,每個線程都有一個獨立的程序計數器。(針對java方法,即棧)
  • 虛擬機棧:為了虛擬機執行java方法,線程創建時就會創建一個棧幀,存儲局部變量表、操作數棧、動態鏈接等。
StackOverFlowError:線程請求的棧深度大於虛擬機所允許的深度;
OutOfMemoryError:動態擴展是無法申請到足夠的內存。
  • 本地方法棧:為了虛擬機使用到Native法服務。
  • 堆:
    存放對象實例和數組,為對象實例分配內存。可分為新生代和老年代。可以處於物理上不連續的內存空間中,只要邏輯上連續即可。
-Xmx和-Xms控制大小。
  • 方法區:存儲類信息、常量、靜態變量、編譯後的代碼等數據。也叫“永久代”,可以像Java堆一樣管理這部分內存。
1.6以後將字符串常量池放入了堆空間。
  • 運行時常量池:存放編譯期生成的各種字面量和符號引用。
intern()方法設計的初衷,就是重用String對象.如下測試驗證。 <wiz_code_mirror>
        String a1 = new String("dog") + new String("Pig");//不會在常量池創建對象。
//        String a1 = new String ("dogPig");//在常量池和堆空間創建對象
        System.out.println(a1 == a1.intern());//在常量池查找不存在,1.6直接生成。1.7直接生成後,指向堆空間的引用。
        System.out.println(a1 == "dogPig");//true
        String str2 = "dogPig";//新加的一行代碼,其余不變
        System.out.println(a1 == str2);//true

內存分配:

桟:存儲對象的引用,局部變量的基本數據類型,速度快,自動銷毀;
堆:存儲new出來的對象,數組,成員變量的基本數據類型;
常量池:屬於方法區,存儲final的變量和方法;
靜態域:屬於方法區,存儲static的變量和方法;
方法區:存儲二進制class字節碼。

Demo demo=new Demo();

這一條語句,其實包括了四個動作:

1)右邊的“new Demo”,是以Demo類為模板,在堆空間裏創建一個Demo對象。
2)末尾的()意味著,在對象創建後,立即調用Demo類的構造函數,對剛生成的對象進行初始化。
3)左邊的“Demo demo”創建了一個Demo類引用變量,它存放在棧空間中。也就是用來指向Demo對象的對象引用。
4)“=”操作符使對象引用指向剛創建的那個Demo對象。

技術分享圖片

java虛擬機內存區域理解