JVM中的內存分配(對象的存儲)

Jvm中的內存分爲:寄存器、棧、堆、常量池、代碼段、數據段

  1. 寄存器:不可控,也是未知

  2. 棧:保存局部變量。而局部變量又包括基本類型和引用類型。對於基本類型來說其中就是保存其“值”,而對於引用類型的來說,這裏存放它的地址,當一個局部變量使用完之後會被立馬釋放掉,但是堆區不會立馬被釋放。另外,局部變量是共享的,也就是說,如果棧中有int i=0,如果再出現int j=0的話,就會讓j指向同一個地址。棧是由棧幀組成的,每個棧幀對應一個方法,並且保存着方法的返回地址,每個線程調用的方法不一樣所以  線程之間不共享

  3. 堆:用以存放動態產生的數據,例如new出來的對象,每個對象有自己獨立的堆塊,其中保存着實例變量,沒有方法,因爲同一個類的方法都是共享的,方法只有在使用的時候纔會加載到內存中,不用不會呆在內存裏。堆中的數據線程之間共享。

  4. 常量池:存在於堆中。用來存放每一個類型的常量,每一個類型都對應着一個常量池。包括直接常量(基本類型和String)、對其它類型、方法、字段的符號引用。池中的數據和數組一樣通過索引訪問。由於常量池包含了一個類型所有的對其他類型、方法、字段的符號引用、所以常量池在java動態來凝結中起到了核心作用。
  5. 代碼段:用來存放從硬盤讀取的源程序。
  6. 數據段:用來存放static定義的靜態成員。
    另一種說法:程序計數器區  棧 堆(線程之間共享數據) 本地方法棧  方法區(線程共享) (存儲了每個類的信息(包括類的名稱、方法信息、字段信息)、靜態變量、常量以及編譯器編譯後的代碼等。

  1. 基本類型:byte short char int long boolean 存在棧區,而 其對應的包裝類則 存在常量池中,也就是堆區,讓門都實現了常量池技術,而double和float的沒有實現,另外String也實現了常量池技術。但是常量池中維護都必須在[-128 127]
  2. 所有的局部變量都是在棧區進行運算的。
    Integer i1=20;
    Integer i2=0;
    Integer i3= new Integer(20);
    那麼 i1+i2==i3 爲true,因爲計算i1+i2的時候,先將他們拆箱放在棧區,然後計算,計算完畢之後沒有裝箱,所以相當於int i4=i1+i2,所以命題爲真。
  1. 常量池的數據是共享的,所以,當有一個“astring”的時候,當在定義另一個“astring”的時候弦查看常量池中有沒有對應的字符串,如果沒有舊添加進去,有的話就用那個。所以:
String aString="astring";
        String bString="astring";
        out.print("aString==bString\t"+(aString==bString));
        輸出:aString==bString  true

但是需要注意的是由+和subString等等操作產生的字符串不是共享的,只有字符串常量是共享的。
所以:

 String aString="astring";
        String bString="astring2".substring(0,7);
        out.print("aString==bString\t"+(aString==bString));
        輸出 aString==bString  false
  1. 當一個類中使用了其他的類中的符號引用是放在常量池中的,實際代碼執行的時候,首次遇到某個別的類的時候,jvm會對常量池中這個類的符號引用展開轉爲直接引用,這樣下次再遇到同樣的類型的時候,jvm就不再解析,而是直接使用這個已經被解析過的直接引用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章