要說Java中的棧,堆,方法區(qū)和常量池就要提到HotSpot,HotSpot是Sun JDK 和 Open JDK中所帶的虛擬機(jī)。 (Sun JDK 和 Open JDK除了注釋不同,代碼實(shí)現(xiàn)基本上是一樣的) 以下說的內(nèi)容都是圍繞HotSpot。
Stack(棧):分為VM Stack(虛擬機(jī)棧)和Native Method Stack(本地方法棧),不過HotSpot虛擬機(jī)直接把本地方法棧和虛擬機(jī)棧合二為一了。 虛擬機(jī)棧: 線程私有的, 描述的是Java方法執(zhí)行的內(nèi)存模型,方法調(diào)用的同時(shí)創(chuàng)建一個(gè)棧幀(儲(chǔ)存局部變量表,操作數(shù)棧,方法出口等等),每個(gè)方法的調(diào)用直到執(zhí)行完成對應(yīng)的是棧幀在虛擬機(jī)中入棧和出棧的過程。 局部變量表(通常說的棧其實(shí)是棧里面的局部變量表):存放基本數(shù)據(jù)類型變量和對象的引用(所需內(nèi)存在編譯時(shí)期完成分配,方法運(yùn)行時(shí)期不改變局部變量表大小,四個(gè)字節(jié)占用一個(gè)局部變量空間)
--------棧中的數(shù)據(jù)可以共享: int a = 3; 包裝類數(shù)據(jù),如Integer,
String, Double等將相應(yīng)的基本數(shù)據(jù)類型包裝起來的類。這些類數(shù)據(jù)全部存在于堆中,Java用new()語句來顯示地告訴編譯器,在運(yùn)行時(shí)才根據(jù)需要?jiǎng)討B(tài)創(chuàng)建,因此比較靈活,但缺點(diǎn)是要占用更多的時(shí)間。
==比較的是對象的地址,也就是是否是同一個(gè)對象; equal比較的是對象的值。 int 變?yōu)镮nteger 時(shí) 如果值在-128~127之間 則不會(huì)創(chuàng)建新的integer對象 儲(chǔ)存常量池中,這么做的目的是提高效率----->記得在別的地方看過不知道對不對
Java代碼 JAVA堆: Java堆是被所有線程共享的一塊區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建 ,此內(nèi)存的唯一目的就是存放對象實(shí)例和數(shù)組 GC 管理的主要區(qū)域。 分為新生代(Eden Survivor Survivor8:1:1)和老年代 Java堆可以處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯連續(xù)即可 關(guān)于對象的創(chuàng)建請參考:http://note.youdao.com/yws/public/redirect/share?id=5177014ee5ad1ac3f0af9fdab3b011a3&type=false
方法區(qū): 不等價(jià)于永久代hotspot用永久代實(shí)現(xiàn)方法區(qū)(在jdk1.7的HotSpot中 已經(jīng)把原本放在永久代中的字符串常量池移出)
與堆一樣是線程共享的一塊內(nèi)存區(qū)域。
用于儲(chǔ)存已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。
垃圾收集行為在方法區(qū)很少出現(xiàn),這塊區(qū)域回收的主要目標(biāo)是針對常量池的回收和對類型的卸載
運(yùn)行時(shí)常量池: 方法區(qū)的一部分
常量池用于存放編譯期生成的各種字面量和符號(hào)引用(還有翻譯出來的直接引用),這部分內(nèi)容在類加載后進(jìn)入方法區(qū)的運(yùn)行時(shí)常量池中存放。
運(yùn)行時(shí)常量池相對于Class文件常量池的另一個(gè)重要特征是具備動(dòng)態(tài)性,運(yùn)行期間也可能將新的常量放入池中
字面量:如文本字符串,聲明為final的常量值等。 public stick final int i =3; String s='abc'; 符號(hào)引用:類和接口的全限定名 字段的名稱和描述符 方法的名稱和描述符
String 的本質(zhì)是字符數(shù)組。
String 的標(biāo)準(zhǔn)實(shí)現(xiàn)含有4個(gè)實(shí)例變量
指向字符數(shù)組的引用
int類型 偏移量
int類型 字符串的長度
int類型 散列值
public class String{
private char[]value;
private int offset;
private int count;
private int hash;
...
}
一個(gè)String對象總共使用40字節(jié)(16字節(jié)對象本身開銷 8字節(jié)的引用 三個(gè)int類型(12字節(jié)) 4字節(jié)(填充字節(jié))),因?yàn)镾tring的char數(shù)組常常是在多個(gè)字符串之間共享的,因此String對象是不可變的
String是一個(gè)特殊的包裝類數(shù)據(jù)。即可以用String str = new String('abc');的形式來創(chuàng)建,也可以用String str = 'abc';的形式來創(chuàng)建 String str = 'abc'創(chuàng)建對象的過程
String str1 = 'abc'; String str2 = 'ab' 'c'; str1==str2是ture
String s = new String(“abc”); 產(chǎn)生幾個(gè)對象? 一個(gè)或兩個(gè),如果常量池中原來沒有 ”abc”, 就是兩個(gè)(參考棧中的數(shù)據(jù)共享)。
|
|