Java常量池的一些思考……

(此博文已移動到.net學習欄目下,主要還是想取消java欄目,因爲我目前的精力主要放在.net學習上。爲何敢移動呢?因爲常量池這塊c#和java在思想上是相通的……)

爲什麼考慮到常量池的問題,是因爲在對於Java中return一個字符串的內存分析時想到的。

舉例:

public String getInfo() {
  return "Name:" + getName() + "\nAge:" + getAge() + "\nSchool" + school;
 }//僅是舉這樣一個例子,在方法getInfo()中返回一個字符串。

System.out.println(person.getInfo()); //這也是舉一個例子,即調用getInfo().

內存分析:當調用getInfo()時,會在data segment(數據區)中存放字符串"Name:" + getName() + "\nAge:" + getAge() + "\nSchool" + school;
然後在棧內存中開闢一塊內存區域,讓這塊內存區域指向data segment中的這個字符串。當打印完後棧內存的那塊引用就會消失,然後數據區中的字符串會等待垃圾回收。

有關常量池的一些思考:(裏邊一些想法也是借鑑了一些大神們的觀點,特此聲明,向他們致敬!)。

容易混淆的概念:我覺得常量池即爲data segment ,雖然好多大神都說常量池在棧中,但是經過各種的內存分析,覺得常量池和data segment都是一樣的內存分析。此處有大神覺得不對的地方,可以對我指教一下!嘿嘿……

常量池:(我吧,主要是講一些有關String跟常量池有關內存分析的一些關係!)

1:String 對象本身:對於new(運行期)出來的對象,將存放於堆中。對於字符串常量(即在編譯期已創建好的,即用雙引號“”定義的)對象存放在常量池中。

2:String s1 = "abc";

String s2 = new String("abc");//第二種是用new()來新建的對象,它會存放在堆中。

3:對於通過new產生一個字符串,會先去常量池中查找是否已有“abc”對象,若沒有則在常量池中創建一個此String對象,然後堆中再創建一個常量池中“abc”對象的拷貝對象。

4:String s1 = "abc"; //abc的值在程序編譯爲.class文件後,就在.class文件中生成了。

5:執行java程序的過程:(1):.class文件生成(2)被jvm裝載到內存執行。

6:String s1 = "abc" + 1; //JVM對於String常量的“+”號連接,編譯器在.class文件中就已經是"abc1",在編譯期其字符串常量的值就確定下來。

7:String s1 = "abc";

       String s2 = "def";

       String s2 = s2 + "java";

//s2先指向一個常量,內容爲def,但此時s2不再指向原來的那個值,而是指向了字符串常量“defjava”,原先變量還存於內存中,等待垃圾回收。

8:String s1 = "abc";注:對象可能並沒有被創建,而可能只是指向一個先前已被創建的一個對象而已。

好了,就是有一些這種感想,其實我覺得對於java常量池,按照data segment的思路去分析內存,應該就可以了……本來常量池也是一個很複雜的問題……就這樣吧……

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章