JAVA8內存模型
對于Java8, HotSpots取消了永久代君账,那么是不是也就沒有方法區(qū)了呢叉瘩?當然不是,方法區(qū)是一個規(guī)范叨吮,規(guī)范沒變,它就一直在瞬矩。那么取代永久代的就是元空間茶鉴。它可永久代有什么不同的?存儲位置不同景用,永久代物理是是堆的一部分涵叮,和新生代,老年代地址是連續(xù)的伞插,而元空間屬于本地內存割粮;存儲內容不同,元空間存儲類的元信息媚污,靜態(tài)變量和常量池等并入堆中舀瓢。相當于永久代的數(shù)據被分到了堆和元空間中。
程序計數(shù)器:它的生命周期與線程相同耗美,線程私有京髓。較小的內存區(qū)域航缀,用以完成分支、循環(huán)堰怨、跳轉芥玉、異常處理、線程恢復等基礎功能备图。不會發(fā)生內存溢出(OutOfMemory=OOM)錯誤灿巧。
虛擬機棧:它的生命周期與線程相同,線程私有揽涮。虛擬機棧中存儲了方法執(zhí)行時相關信息抠藕,每個方法在調用時都會在虛擬機棧中創(chuàng)建一個方法幀,方法幀中包含了局部變量绞吁,參數(shù)幢痘,運行中間結果等信息。幀數(shù)超過限制(-Xss)家破,就會出現(xiàn)StackOverFlow(=SOF)錯誤颜说。另外超過線程分配的內存大小,也會報OOM錯誤汰聋。
本地方法棧:它的生命周期與線程相同门粪,線程私有∨肜В基本同虛擬機棧玄妈。存放的是native方法幀∷杳罚可出現(xiàn)SOF和OOM錯誤拟蜻。
元空間(MetaSpace):所有線程共享。存放class加載相關信息枯饿。
堆:所有線程共享酝锅。存放new出來的數(shù)組和對象數(shù)據,以及類的靜態(tài)變量奢方。同時搔扁,包含一個
常量池(final),是由1.7以前版本的方法區(qū)轉移過來的
蟋字。
示例:
- str1==str2 指向同一個堆對象稿蹲,同時創(chuàng)建了一個常量池引用。
- str3 創(chuàng)建了3個堆對象鹊奖,只創(chuàng)建了一個常量池引用苛聘。
- str4 創(chuàng)建了2個堆對象,其中有個對象的value引用另一個的value地址,并未創(chuàng)建常量池引用设哗。
另外補充幾點關于String的總結:
- 字面量方式聲明璧尸,查找常量池有則返回引用。否則熬拒,堆里生成對象,同時在在常量池生成引用垫竞。如:String s = "xyz";
- 字面量相+澎粟,根據+的結果查找常量池有則返回引用,否則欢瞪,堆里生成對象活烙,同時在常量池生成引用。如:String s = "a"+"b"; 常量池查找“ab”遣鼓。最多生成三個對象啸盏。
- 字符串相+,如果有一個不是字面量骑祟,則必在堆里生成一個新對象回懦,常量池不生成引用。如:String s=s1+"a";