jvm学习笔记(三)
jvm學習筆記(三)
文章目錄
- jvm學習筆記(三)
- 1.全部筆記鏈接
- 2.堆
- 2.1堆的劃分
- 使用JVM參數查看劃分
- Hotspot堆內存劃分圖(JDK8之前)
- 2.2 GC對堆的回收
- GC的種類
- MinorGC的過程
- MajorGC的過程(Old GC)
- Full GC
- 2.3 一些調節參數
- 3. OOM
- 3.1 簡介
- 3.2 排錯
1.全部筆記鏈接
JVM學習筆記(一)
JVM學習筆記(二)
JVM學習筆記(三)
JVM學習筆記(四)
(待更新…)
2.堆
是被線程共享的一塊內存區域,創建的對象和數組都保存在 Java 堆內存中,也是垃圾收集器進行
垃圾收集的最重要的內存區域。由于現代 VM 采用分代收集算法, 因此 Java 堆從 GC 的角度還可以
細分為: 新生代(Eden 區、From Survivor 區和 To Survivor 區)和老年代。
2.1堆的劃分
關于堆的劃分,需要明確一點:
- 邏輯上堆是包含新生代,老年代和永久代(JDK1.8叫元空間)
- 物理上應該是:新生代+老年代,在JDK1.8后,永久代變成了元空間,并且元空間被移到本地內存,而不再虛擬機內存中。
使用JVM參數查看劃分
-Xms1024m -Xmx1024m -XX:+PrintGCDetails一般查看PrintGCDetails都會帶上PermGen區(永久代),雖然可以查看打印信息中有Young Generation,Old Generation,PermGen(或者Metaspace),當是計算的時候會發現Heap=Young Generation+Old Generation。
永久代:(方法區,不屬于java堆,另一個別名為“非堆Non-Heap”)
Hotspot堆內存劃分圖(JDK8之前)
Heap劃分為:
- Young Generation(占1/3)
- Old Generation(占2/3)
Young Generation又劃分為:
- Eden Space(伊甸園,占8/10)
- From Space(幸存區1,占1/10)
- To Space(幸存區2,占1/10)
From Space和To Space是兩個幸存區,而這兩個區域并非一成不變,這兩個區域在GC的過程會進行交換。
2.2 GC對堆的回收
GC的種類
GC用來回收堆中不再使用的對象,GC分兩種:
- MinorGC(輕GC)
- MajorGC (重GC)
一般情況下,會觸發MinorGC,MajorGC 不會頻繁執行。
之前看復習資料以為GC單純兩種,后來發現還要其他GC模式,然后上網查閱了相關資料,然后得出以下結論:
以下內容來自知乎: https://www.zhihu.com/question/41922036
針對HotSpot VM的實現,它里面的GC其實準確分類只有兩大種:
-
Partial GC:并不收集整個GC堆的模式
-
- Young GC:只收集young gen的GC
- Old GC:只收集old gen的GC。只有CMS的concurrent collection是這個模式
- Mixed GC:收集整個young gen以及部分old gen的GC。只有G1有這個模式
-
Full GC:收集整個堆,包括young gen、old gen、perm gen(如果存在的話)等所有部分的模式。
Major GC通常是跟full GC是等價的,收集整個GC堆。但因為HotSpot VM發展了這么多年,外界對各種名詞的解讀已經完全混亂了,當有人說“major GC”的時候一定要問清楚他想要指的是上面的full GC還是old GC。
作者:RednaxelaFX
鏈接:https://www.zhihu.com/question/41922036/answer/93079526
來源:知乎
MinorGC的過程
由于頻繁創建對象,所以新生代會頻繁觸發MinorGC 進行垃圾回收。當 Eden 區內存不夠的時候就會觸發 MinorGC,對新生代區進行一次垃圾回收。MinorGC使用的是復制算法,過程如下:
MajorGC的過程(Old GC)
老年代的對象比較穩定,所以 MajorGC 不會頻繁執行。大部分對象會在MinorGC過程中消亡,而一般只有部分的能進入老年代。在進行 MajorGC 前一般都先進行了一次 MinorGC,使得有新生代的對象晉身入老年代,導致空間不夠用時才觸發。MajorGC 通常采用標記清除算法或標記整理算法(其實也不能說MajorGC就是標記清除算法,使用哪種算法對老年代進行垃圾回收完全取決于使用的那種垃圾回收器),垃圾回收器將在其他學習筆記中的介紹,現在先說一下標記清除算法,標記清除算法過程如下:
- 首先掃描一次所有老年代,標記出存活的對象。
- 然后回收沒有標記的對象。
Full GC
當準備要觸發一次young GC時,如果發現統計數據說之前young GC的平均晉升大小比目前old gen剩余的空間大,則不會觸發young GC而是轉為觸發full GC(因為HotSpot VM的GC里,除了CMS的concurrent collection之外,其它能收集old gen的GC都會同時收集整個GC堆,包括young gen,所以不需要事先觸發一次單獨的young GC);或者,如果有perm gen的話,要在perm gen分配空間但已經沒有足夠空間時,也要觸發一次full GC;或者System.gc()、heap dump帶GC,默認也是觸發full GC。
作者:RednaxelaFX
鏈接:https://www.zhihu.com/question/41922036/answer/93079526
2.3 一些調節參數
調節堆
#調節大小 -Xmx -Xms #控制Eden和Survivor的比例 -XX:SurvivorRatio #調節Young和Old的比例 -XX:NewRatio #調節永久代初始大小(JDK1.8不用了) -XX:PermSize #調節永久代大小最大值 -XX:MaxPermSize垃圾回收的一些參數
#垃圾最大年齡 -XX:MaxTenuringThreshold3. OOM
3.1 簡介
OOM,全稱“Out Of Memory”,源于java.lang.OutOfMemoryError。當JVM因為沒有足夠的內存來為對象分配空間并且垃圾回收器也已經沒有空間可回收時,就會拋出這個error。
3.2 排錯
內存快照分析工具,MAT,Jprofiler。作用分析Dump內存文件,快速定位內存泄漏。
輸出Dump文件
#內存泄漏時輸出dump文件 -XX:HeapDumpOnOutOfMemoryError #重GC前輸出dump文件 -XX:+HeapDumpBeforeFullGC #指定dump文件目錄 -XX:HeapDumpPath=xxx輸出Dump文件**
#內存泄漏時輸出dump文件 -XX:HeapDumpOnOutOfMemoryError #重GC前輸出dump文件 -XX:+HeapDumpBeforeFullGC #指定dump文件目錄 -XX:HeapDumpPath=xxxdump出來的內存文件,用Jprofiler可以查看到其內存分配情況,并且通過線程快照 可以查看到在哪一行代碼導致內存泄漏。
總結
以上是生活随笔為你收集整理的jvm学习笔记(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jvm学习笔记(二)
- 下一篇: 客户电脑买来才一年客户电脑买来才一年就坏