棧 堆 方法區 常量池

2022-10-09 16:18:07 字數 1849 閱讀 9948

存放j**a在函式中定義的基本型別的變數的引用和資料,以及物件的引用都放在棧中儲存。

主要存放new出來的物件和陣列。

儲存已經被虛擬機器載入的類資訊、常量、靜態變數,即編譯器編譯後的**等資料。

靜態變數、常量在方法區;所有方法,包括靜態和非靜態的,也在方法區。

靜態常量池

靜態常量池存在於class檔案中。

執行時常量池

執行時常量池,就是在class檔案被載入進了記憶體之後,常量池儲存在了方法區中,通常說的常量池值的是執行時常量池。所以呢,討論的都是執行時常量池。

字串常量池

string a = "abc";

string b = new string("abc");

system.out.println(a==b);

結果:false

物件b儲存在堆中,這個是不用質疑的,

而a作為字面量一開始儲存在了class檔案中,之後執行期,轉存至方法區中。

它們兩個就不是同乙個地方儲存的。

例項
string s1 = "hello";

string s2 = "hello";

string s3 = "hel" + "lo";

string s4 = "hel" + new string("lo");

string s5 = new string("hello");

string s6 = s5.intern();

string s7 = "h";

string s8 = "ello";

string s9 = s7 + s8;

system.out.println(s1 == s2); // true; s1 和 s2 都指向了方法區常量池中的hello。

system.out.println(s1 == s3); // true; 因為做+號的時候,會進行優化,自動生成hello賦值給s3,所以也是true

system.out.println(s1 == s4); // false; s4是分別用了常量池中的字串和存放物件的堆中的字串,做+的時候會進行動態呼叫,最後生成的仍然是乙個string物件存放在堆中。

system.out.println(s1 == s9); // false; 在j**a9中,因為用的是動態呼叫,所以返回的是乙個新的string物件。所以s9和s4,s5這三者都不是指向同一塊記憶體

system.out.println(s1 == s6); // true; 歸功於intern方法,這個方法首先在常量池中查詢是否存在乙份equal相等的字串如果有的話就返回該字串的引用,沒有的話就將它加入到字串常量池中,所以存在於class中的常量池並非固定不變的,可以用intern方法加入新的.

public class test 

}// 我們可以發現,

// 對於final型別的常量它們已經在編譯中被確定下來,

// 自動執行了+號,把它們拼接了起來,所以就相當於執行了"123" + "456";

public class test2 

public static void main(string args)

}// 上個例子是在編譯期間,

// 就已經確定了a和b,但是在這段**中,

// 編譯期static不執行的,a和b的值是未知的,

// static**塊,在初始化的時候被執行,初始化屬於類載入的一部分,

// 屬於執行期。看看反編譯的結果,很明顯使用的是indy指令,

// 動態呼叫返回string型別物件。

// 乙個在堆中乙個在方法區常量池中,自然是不一樣的。

c 棧區 堆區 常量區

c 中棧區 堆區 常量區 由一道面試題目而學習 2009 04 28 21 01 include void main 對應的彙編 10 a c 1 00401067 8a 4d f1 mov cl,byte ptr ebp 0fh 0040106a 88 4d fc mov byte ptr ebp...

C 中棧區 堆區 常量區

c 中棧區 堆區 常量區 由一道面試題目而學習 2009 04 28 21 01 include void main 對應的彙編 10 a c 1 00401067 8a 4d f1 mov cl,byte ptr ebp 0fh 0040106a 88 4d fc mov byte ptr ebp...

堆區 棧區 靜態區 常量區還有???

常見的儲存區域可分為 由編譯器在需要的時候分配,在不需要的時候自動清楚的變數的儲存區。裡面的變數通常是區域性變數 函式引數等。由new分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般乙個new就要對應乙個delete。如果程式設計師沒有釋放掉,程式會一直占用記憶體,導致記憶體洩漏...