JVM變數和值的儲存位置
阿新 • • 發佈:2018-11-08
今天看java程式設計思想的時候看到了“引用”這個詞,忽然對java中變數和值的儲存結構有點迷糊,然後百度找了好久才找到,還是記錄一下好了,加深一下印象。
1.JVM的儲存結構
- 暫存器:最快的儲存區,位於處理器內部,由編譯器根據需求進行分配,我們在程式中無法控制
- 棧:位於通用RAM(隨機訪問儲存器),方法執行時建立方法棧幀,存放基本資料型別的變數資料和物件的引用。但物件本身不存放在棧中,而是存放在堆(new出來的物件)或者常量池中(字串常量物件存放在常量池中)
- 堆:存放所有new出來的物件
- 靜態域(方法區):存放靜態成員(static定義的)
- 常量池(方法區):存放字串常量和基本型別常量(public static final)
- 非RAM儲存:硬碟等永久儲存空間
這裡主要關注棧、堆、常量池,其中,儲存在棧和常量池中的物件是可以共享的,而堆中的物件不能共享。棧中的資料大小和生命週期是可以確定的,當沒有引用指向資料時,這個資料就會消失。堆中的物件的由垃圾回收器負責回收,因此大小和生命週期不需要確定,具有很大的靈活性。
舉兩個很簡單的例子就能很容易理解了:
第一個例子:
String s1 = "china"; String s2 = "china"; String s3 = "china"; String ss1 = new String("china"); String ss2 = new String("china"); String ss3 = new String("china");
其中黑色的線表示的是引用,每一次new,都會在堆中新建一個new物件,而當前這個例子中,它會先去常量池中查詢“china”物件,如果有,就引用,如果沒有,就在常量池中新建一個“china”物件。
其中有個點需要標明一下,在最開始的時候說了,常量池中儲存的是public static final物件,那字串常量為什麼能夠存進去呢?這裡需要解釋一下,String並不是八大基本資料型別,它是一個類,並且該類的修飾符就是public static final,這也是String是靜態字串常量的說法由來,也就能夠理解為什麼說String的每一次改變,都是新建一個String物件了。
第二個例子:
int i1 = 9;
int i2 = 9;
int i3 = 9;
public static final int INT1 = 9;
public static final int INT2 = 9;
public static final int INT3 = 9;
這個例子就很明顯的表示出了棧和常量池的資料型別儲存的區別:基本資料型別的變數資料存放在棧中,而public static final修飾的變數資料就都存放在常量池中。