JVM內(nèi)存筆記

JVM(Java虛擬機),最常見的就是HotSpot VM,相信所有Java程序員都知道,它是Sun JDK和OpenJDK中所帶的虛擬機,也是目前使用范圍最廣的Java虛擬機。

JVM堆內(nèi)存和非堆內(nèi)存

JDK1.8開始MetaSpace(元空間)取代(Perm)永久代

官方的說法:“Java 虛擬機具有一個堆(Heap),堆是運行時數(shù)據(jù)區(qū)域,所有類實例和數(shù)組的內(nèi)存均從此處分配。堆是在 Java 虛擬機啟動時創(chuàng)建的。”“在JVM中堆之外的內(nèi)存稱為非堆內(nèi)存(Non-heap memory)”。

Java 虛擬機具有一個堆,堆是運行時數(shù)據(jù)區(qū)域,所有類實例和數(shù)組的內(nèi)存均從此處分配。堆是在 Java 虛擬機啟動時創(chuàng)建的。對象的堆內(nèi)存由稱為垃圾回收器的自動內(nèi)存管理系統(tǒng)回收。

1、Java 內(nèi)存分為3個代:堆內(nèi)存有【New(新生代)、Old(老年代)】,Perm(永久代)

堆內(nèi)存:一般存放new出來的對象,存放數(shù)組等;

非堆內(nèi)存(永久代):存放靜態(tài)變量、常量、方法

2、堆內(nèi)存有:new(新生代)、old(老年代)

①年輕代分為:1個伊甸園區(qū)(eden)、2個存活區(qū)(survivor)

②這2個存活區(qū)大小相等,位置互換(所謂的位置互換:每一次YGC,總會有一個存活區(qū)是空的)


3、new出來的對象優(yōu)先分配在伊甸園區(qū),新的對象不斷進入eden,只有當eden區(qū)滿了后,才觸發(fā)YoungGC;

觸發(fā)YGC時,JVM先判斷對象是不是有引用指向它(通過尋根遍歷,從根節(jié)點進行判斷),然后做2件事:

①如果是沒有引用指向的對象,則當成垃圾回收掉;

②如果是有引用指向的對象,則把該對象放到存活區(qū)(s0或者s1)里;此時eden區(qū)就空了。又可以繼續(xù)放新的對象。eden如果再次滿了,則第二次觸發(fā)YGC。

圖1

觸發(fā)YoungGC的過程

4、下圖是第一次觸發(fā)YGC,YGC只會在伊甸園區(qū)觸發(fā),伊甸園區(qū)滿了就觸發(fā)YGC

圖2

5、第二次觸發(fā)YGC,會判斷eden的對象是否有引用指向,s0里是否有引用。s0變成了s1,s1成了s0;

圖3

6、第三次觸發(fā)YGC:對于eden,如果有引用指向的對象,就繼續(xù)放到存活區(qū)s0;沒有引用指向的對象就當做垃圾回收掉。對于存活區(qū)s1,會被判斷是否有引用指向,然后放入到s0區(qū),s1空了。

圖4?會不斷重復上面的過程(第一次觸發(fā)、第二次觸發(fā)......)

6、問:YGC觸發(fā)后,是把所有的有引用的對象都放到S0后,新的對象才能進入eden嗎?

答:YGC觸發(fā)后或者FGC觸發(fā)后,整個java應用程序線程是暫停的(應用程序不干活),只進行垃圾回收。如果這個垃圾回收時間很長,用戶就感覺到慢了,這應該就是影響性能問題的地方。

7、老年代(old):【大對象】和【長期存活的對象】直接進入老年代;

eden放不下這些大對象,【大對象】直接放進老年代;

長期存活的對象:默認年齡等于15(此值可更改),也就是執(zhí)行了15次YGC還存在的對象

第一次出現(xiàn)YGC,此對象就在存活區(qū),此時對象年齡+1,

第二次出現(xiàn)YGC,此對象還在存活區(qū),此時對象年齡再+1,

如此到15次,此對象還在存活區(qū),則放入老年代。

圖5

8、Full?GC一般會在3種情況下觸發(fā):

?????①老年代滿的時候觸發(fā)Full?GC(FGC),對整個堆內(nèi)存和非堆內(nèi)存進行垃圾回收。

??FGC一般會用20多秒時間。JVM調(diào)優(yōu)時:盡量減少FGC出現(xiàn)頻率(也是垃圾回收核心原理)

?????②持久代(非堆內(nèi)存)滿的時候,也觸發(fā)FGC

③被顯式調(diào)用(代碼里執(zhí)行system.GC()??Runtime.gc();可以在JVM里disable掉)、?執(zhí)行了悲觀策略(比如jmap和dump的時候)。

觸發(fā)第一次FGC,老年代中的對象沒有被回收徹底,如此5次還是有對象沒有被徹底回收,就會報(out?of?memory)等錯誤。

圖6
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 轉載blog.csdn.net/ning109314/article/details/10411495/ JVM工...
    forever_smile閱讀 5,508評論 1 56
  • 一、類加載機制 Java字節(jié)碼 我們編寫好的代碼是 .java文件,并不能交給機器直接執(zhí)行, 需要將其編譯成為.c...
    斯文遮陽閱讀 677評論 1 2
  • jstack-- 如果java程序崩潰生成core文件,jstack工具可以用來獲得core文件的java sta...
    not_null閱讀 8,222評論 2 62
  • JVM架構 當一個程序啟動之前,它的class會被類裝載器裝入方法區(qū)(Permanent區(qū)),執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,846評論 0 7
  • 作者:一字馬胡 轉載標志 【2017-11-12】 更新日志 日期更新內(nèi)容備注 2017-11-12新建文章初版 ...
    beneke閱讀 2,331評論 0 7

友情鏈接更多精彩內(nèi)容