Java核心篇之JVM--day3
?Java核心篇之JVM--day3 ? ? ??
?Java JVM詳解--通俗易懂教程
?
?
JVM:Java虛擬機的簡稱。
談到JVM,通常會聊到三個問題:
1. 什么時候觸發Java GC?
2. 對什么東西進行Java GC?
3. 如何進行Java GC?
?
首先解決第一個問題:
1. 什么時候觸發Java GC?
GC分為minor GC和Full GC。
Full GC:
2. 對什么東西進行GC ?對GC root搜索不到,并且經過第一次標記,清除之后,仍然沒有復活的對象進行GC。
3. 做了什么工作,怎么進行GC?
主要做了清理對象,整理內存的工作,Java堆中主要是有新生代和年老代,他們采用不同的回收方式,例如新生代采用了標記復制的算法(因為其生存時間比較短),新生代進行gc的時候,會把eden區存活的對象放到另外一個survival區域里面,然后把eden區和另外一個survival區清除。而年老代采用了標記清除的算法,首先標記出存活的對象,然后移到另一端,這樣也能減少內存碎片化。
?
?
?
垃圾收集有哪些算法?
標記清除算法:標記出需要回收的對象,標記完成后,統一回收所有被標記的對象。(兩個不足:效率不高:標記和清除都不高;空間問題:產生大量不連續的內存碎片,可能導致以后在分配較大對象的時候因無法找到連續的內存而觸發GC)
復制算法:(新生代)比較適合對象存活率比較低的場景。應用于新生代,它主要是把內存分成兩個塊,每次只使用一塊,就像新生代一樣,有兩個區域:一個是eden區,一個是survival區。這樣也就解決了內存碎片化的問題。
標記整理算法:(老年代)比較適合對象存活率比較高的場景,應用于老年代,將所有存活對象都移向另一端,然后直接清除掉端邊界外的內存。
?
?
如何判斷對象是否存活?
引用計數法:每個對象都有一個引用計數器,當對象被引用一次的時候,計數器+1,當對象引用失效的時候,計數值-1,實時性,當對象的引用計數器的值為0,則立刻回收,不能解決循環引用的問題。
可達性算法分析:從GC Root作為起點開始搜索,,那么整個連通圖的對象都是存活的對象,對于GC Root無法到達的對象便成了垃圾回收的對象。(解決循環引用的問題)
?
?
常用的引用:
強引用>軟引用>弱引用>虛引用
強引用:GC永遠都不會回收的對象。內存空間不足時,寧愿拋出OutOfMemoryError。
軟引用:內存空間不足時會考慮回收它,空間足夠的時候不會
弱引用:不管內存空間夠不夠,都會回收它。
虛引用:不會影響生存時間,目的是能在這個對象被收集器回收時收到一個系統通知。
?
虛擬機棧中的對象
方法區的靜態變量
方法區常量池的對象
?
?
?
?
?
分為新生代收集器,老年代收集器:
新生代收集器:
在執行機制上JVM主要提供了串行GC(serial GC),并行GC(ParNew),并行回收GC(parallel scavenge)
Serial GC:在整個GC的過程中采用單線程的方式來進行垃圾回收,在回收過程中,必須停止其他所有的工作線程。 適用于單CPU,是client模式下默認的GC方式。
parNew :其實就是serialGC的多線程版本,除了使用多條線程來進行垃圾收集之外,其他行為跟serialGC差不多。,是server模式下默認使用的GC方式。能夠與CMS收集器配合工作。
Parallel scavenge:它跟parNew差不多,也是一個并行的多線程收集器。不過他的關注點跟其他收集器不一樣。Cms等收集器的關注點是盡可能的縮短垃圾收集是用戶線程的停頓時間,而parallel scavenge的目的是為了達到一個可控制的吞吐量。(也就是CPU用于運行用戶代碼的時間與CPU總的消耗時間的比值)還有一個就是parallel scavenge有GC的自適應調節策略:我們可以通過一個參數,這個參數叫做userAdaptiveSizePolicy來讓虛擬機幫我們動態的調整這些參數以提供最合適的停頓時間或者最大的吞吐量。
?
?
老年代收集器:
?
串行GC(serial old):他是serial的老年代版本,也是一個單線程收集器,使用標記整理算法。
并行GC(parallel old):是parallel scavenge 的老年代版本。使用多線程和“標記-整理”算法。
?
?
并發GC(CMS):獲取最短回收停頓時間為目標的收集器。
優點是:并發收集,低停頓
總結如下:
缺點有三:
(cpu數量+3)/4,當cpu<4的時候,占用了不少于25%的cpu資源。(增量式并發收集器:讓他們交替執行)
?
成熟的收集器:
G1:G1收集器是當今收集器技術發展最前沿的成果,他是一款面向服務端應用的收集器。
過程如下:
- 初始標記:標記一下GC root能直接關聯到的對象。,需要停頓線程,耗時短。
- 并發標記:從gc root開始對堆中的對象進行分析,找出存活的對象,耗時長,但是可以和用戶線程并發執行。
- 最終標記:為了修正在并發標記過程中因用戶程序繼續運作而導致標記產生變動的那一部分標記記錄。這個階段需要停頓用戶線程。
- 篩選回收:首先對各個region的回收價值和成本進行排序,根據用戶所期望的停頓時間來指定回收計劃。
優勢:
?
垃圾收集器參數總結:
?
?
userSerialGC:虛擬機運行在client模式下的默認值,打開此開關之后,使用serial+serial old組合收集器。
userParNewGC:打開此開關之后,使用parNew+serial Old組合收集器。
userConcMarkSweepGC:打開此開關之后,使用parNew+CMS+serial Old組合垃圾收集器,serial old作為后備收集器使用。(concurrent mode failure)
userParallelGC:server模式下的默認值,parallel Scavenge+serial old組合垃圾收集
userParallelOldGC:parallel scavenge+parallel old收集器組合收集。
SurvivalRadio:eden:survival= 8
userAdaptiveSizePolicy:GC自適應調節策略,調整Java堆各區域的大小以及進入老年代的年齡。
handlePromotionFailure:是否允許分配擔保失敗
ParallelGCThreads:設置并行GC時進行內存回收的線程數。
?
?
?
總結
以上是生活随笔為你收集整理的Java核心篇之JVM--day3的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot————JPA快速使
- 下一篇: Java工具方法——属性拷贝方法:Bea