? ?????jvm虛擬內存分布:
? ??程序計數器是jvm執(zhí)行程序的流水線,存放一些跳轉指令摘盆。
? ? ?本地方法棧是jvm調用操作系統(tǒng)方法所使用的棧。
? ? ?虛擬機棧是jvm執(zhí)行java代碼所使用的棧刹勃。
? ? ?方法區(qū)存放了一些常量剩蟀、靜態(tài)變量、類信息等苦酱,可以理解成class文件在內存中的存放位置售貌。(在jdk8中,移除了方法區(qū)疫萤,轉而用Metaspace區(qū)域替代)
? ? ?虛擬機堆是jvm執(zhí)行java代碼所使用的堆颂跨。
Java中的常量池,實際上分為兩種形態(tài):靜態(tài)常量池和運行時常量池扯饶。
? ??靜態(tài)常量池:
?????*.class文件中的常量池恒削,每個class文件都有一個class常量池池颈。這種常量池主要用于存放兩大類常量:字面量(Literal)和符號引用量(Symbolic References)
????字面量包括:1.文本字符串 2.八種基本類型的值 3.被聲明為final的常量等;
????符號引用包括:1.類和方法的全限定名 2.字段的名稱和描述符 3.方法的名稱和描述符。
? ??運行時常量池:
????JVM在執(zhí)行某個類的時候钓丰,必須經過加載躯砰、連接、初始化携丁,而連接又包括驗證弃揽、準備、解析三個階段则北。而當類加載到內存中后,jvm就會將class文件中的常量池載入到內存中痕慢,并保存在方法區(qū)中尚揣。運行時常量池相對于CLass文件常量池的另外一個重要特征是具備動態(tài)性,字面量可以動態(tài)的添加(String類的intern()方法),符號引用可以被解析為直接引用掖举。Java語言并不要求常量一定只有編譯期才能產生快骗,也就是并非預置入CLass文件中常量池的內容才能進入方法區(qū)運行時常量池,運行期間也可能將新的常量放入池中塔次,這種特性被開發(fā)人員利用比較多的就是String類的intern()方法方篮。當調用 intern 方法時,如果池已經包含一個等于此 String 對象的字符串(用 equals(Object) 方法確定)励负,則返回池中的字符串藕溅。否則,將此 String 對象添加到池中继榆,并返回此 String 對象的引用巾表。
? ??常量池的好處
????常量池是為了避免頻繁的創(chuàng)建和銷毀對象而影響系統(tǒng)性能,其實現了對象的共享略吨。
????例如字符串常量池集币,在編譯階段就把所有的字符串文字放到一個常量池中。
????(1)節(jié)省內存空間:常量池中所有相同的字符串常量被合并翠忠,只占用一個空間鞠苟。
????(2)節(jié)省運行時間:比較字符串時,==比equals()快秽之。對于兩個引用變量当娱,只用==判斷引用是否相等,也就可以判斷實際值是否相等考榨。
? ? ==比equals()快的原因:
????在java 中趾访,直接使用==操作符,比較的是兩個字符串的引用地址董虱。
????instanceof 是 Java 的一個二元操作符扼鞋,類似于 ==申鱼,>,< 等操作符云头。是 Java 的保留關鍵字捐友。它的作用是測試它左邊的對象是否是它右邊的類的實例,返回 boolean 的數據類型溃槐。
? ? 通過string類的eeqquals方法的源碼可以看出調用equals方法匣砖,會先判斷字符串和參數是否引用的同一個地址,不是同一對象的話才會比較值昏滴。
使用常量池的例子: