1. 程式人生 > >JVM變數和值的儲存位置

JVM變數和值的儲存位置

今天看java程式設計思想的時候看到了“引用”這個詞,忽然對java中變數和值的儲存結構有點迷糊,然後百度找了好久才找到,還是記錄一下好了,加深一下印象。

1.JVM的儲存結構

  1. 暫存器:最快的儲存區,位於處理器內部,由編譯器根據需求進行分配,我們在程式中無法控制
  2. 棧:位於通用RAM(隨機訪問儲存器),方法執行時建立方法棧幀,存放基本資料型別的變數資料和物件的引用。但物件本身不存放在棧中,而是存放在堆(new出來的物件)或者常量池中(字串常量物件存放在常量池中)
  3. 堆:存放所有new出來的物件
  4. 靜態域(方法區):存放靜態成員(static定義的)
  5. 常量池(方法區):存放字串常量和基本型別常量(public static final)
  6. 非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修飾的變數資料就都存放在常量池中。