棧、堆、常量池等雖同屬Java內存分配時操做的區域,但其適用範圍和功用卻大不相同。本文將深刻Java核心,簡單講解Java內存分配方面的知識。數組
首先咱們先來說解一下內存中的各個區域。spa
存放基本類型的數據和對象的引用,即存放變量。.net
若是存放的是基本類型數據(非靜態變量),則直接將變量名和值存入stack中的內存中;code
若是是引用類型,則將變量名存入棧,而後指向它new出的對象(存放在堆中)。對象
存放new產生的數據。接口
分爲靜態域和常量域。內存
存放在對象中用static定義的靜態成員(即靜態變量,同理,若是該靜態變量是基本類型則將變量名和值存入靜態域,若是是引用類型則指向new出的對象)。get
常量池指的是在編譯期被肯定,並被保存在已編譯的.class文件中的一些數據。除了包含代碼中所定義的各類基本類型(如int、long等)和對象型(如String及數組)的常量值(final)還包含一些以文本形式出現的符號引用,好比:類和接口的全限定名;字段的名稱和描述符;方法和名稱和描述符。編譯
code segment:存放代碼。class
下面我來舉幾個簡單的小例子來讓你們認識一下這幾個區域具體存放的內容:
注:例1和例2中你們要注意String類型不是基本數據類型,因此它能夠建立對象,而且它的值是放在常量池中的。
String str = "abc"; static Int a = 10; //建立String類型的變量str;建立Int類型變量a
內存解析:
這裏的str是非靜態變量因此將其放入到棧中,而靜態變量a則須要放入靜態域中,對於變量值"abc"和10則都應該放入到常量池當中
String str=new String("abc"); //建立String類型的對象str
內存解析:
這裏的str是String類型的對象,因此放入棧中,而new出來的東西則放入到堆中,對於初始值"abc"則放入到常量池中便可。
Int s[] = new Int[3];s[0]=3;s[1]=2;s[2]=3;
內存解析:
這裏的s[]是一個數組變量,因此放入到棧中,new出來的東西仍是放入到堆中,最後的每一個元素的值則放入到常量池當中。