網站首頁 編程語言 正文
目錄
1.垃圾收集算法
1.1 標記-復制算法
1.2 標記-清除算法
?1.3 標記-整理算法
?2.垃圾收集器
?2.1 Serial收集器
?2.2 Parallel Scavenge收集器
?2.3 ParallelNew收集器
?2.4 CMS收集器
3.電商系統(tǒng)優(yōu)化JVM參數(shù)設置
4. 三色標記原理
1.垃圾收集算法
常用的垃圾收集算法:分代收集理論(年輕代和老年代分別使用不同的垃圾回收算法),標記-復制算法(年輕代),標記整理算法(老年代),標記清除算法(老年代)。
1.1 標記-復制算法
?標記復制算法,會將內存分為兩塊,一半使用過的內存塊,一半未使用的內存塊,在進行垃圾收集時,將還存活的對象復制整理到未使用的內存塊,整理過后將使用過的內存塊清除。
主要在年輕代中使用這個算法。
缺點:浪費內存,每次1G的內存只能使用500M。
1.2 標記-清除算法
標記出所有存活的對象或者標記所有可回收的對象,標記-清除算法會產生兩個問題:
1. 效率問題:如果需要標記存活的對象太多會無法標記。
2. 空間問題:標記清理完成以后會產生大量的內存塊,如果需要一整塊連續(xù)的內存就會導致內存無法分配。
主要用于老年代中。
?
?1.3 標記-整理算法
通過標記垃圾對象將垃圾對象往存活對象一端移動,這樣最終生成的內存空間是一端連續(xù)的內存塊,存活對象和可使用對象。
?2.垃圾收集器
分代收集器:
????????年輕代:serial,ParNew,Parallel
????????老年代:CMS SerialOld Parallel Old
不分代算法:
? ? ? ? G1等,其他了解即可。
為什么要設計這么多垃圾收集器?就是因為內存在不斷變大,市面上沒有一種完美的垃圾收集器,都在不停完善中。垃圾收集算法是方法論,垃圾收集器是垃圾收集算法的具體實現(xiàn)。
tips:在大內存3-4G情況下推薦使用CMS收集器,如果只有2-3G使用Parallnel收集器,因為Parallnel收集器更關注吞吐量,STW只有一個過程集中用來垃圾回收,相對應STW時間會更短,但是CMS在大內存情況下犧牲了時間,為了用戶體驗至上,只有2個STW時間,最耗時間的并發(fā)標記不STW,用戶體驗上來說更好。
JDK8推薦CMS垃圾收集器,jdk9推薦使用G1垃圾收集器。jdk11推薦使用ZGC垃圾收集器。
JVM調優(yōu)例子,8G的內存分配4G給JVM,參數(shù)如下,按照順序 堆初始內存;堆最大內存 ;年輕代大小;桟線程大小;元空間初始值;元空間最大初始值 ;年輕代三個區(qū)域比例(Eden:S0:S1)=8:1:1 ;年輕代分代年齡(minor GC次數(shù));大對象
‐ Xms3072M ‐ Xmx3072M ‐ Xmn2048M ‐ Xss1M ‐ XX : MetaspaceSize = 256 M ‐ XX : MaxMetaspaceSize = 256 M ‐ XX : SurvivorRatio = 8?‐ XX : MaxTenuringThreshold = 5 ‐ XX : PretenureSizeThreshold = 1 M
?2.1 Serial收集器
使用單線程實現(xiàn)垃圾回收,每次垃圾回收時都會停止所有工作線程專心做垃圾回收算法,也叫STW(Stop The World)。
優(yōu)點:簡單,適合于單核CPU中,幾十M的內存。
缺點:無法適用于現(xiàn)在多CPU電腦。效率低下。
年輕代和老年代都可以使用serial收集器:-XX:+UseSerialGC -XX:+UseSerialOldGC
新生代使用復制算法,老年代使用標記-整理算法。
?2.2 Parallel Scavenge收集器
并行垃圾收集器,跟serialn收集器不一樣的是在垃圾收集時使用多線程去垃圾回收。
年輕代和老年代都可以使用parallel收集器:-XX:+UseParallelGC?-XX:+UseParallelOldGC
還可以使用-XX:ParallelGCThreads指定線程收集垃圾,一般與計算機CPU核數(shù)相同。不建議修改。
新生代使用復制算法,老年代使用標記-整理算法。
jdk8默認使用這個垃圾收集器。
?2.3 ParallelNew收集器
ParallelNew收集器跟Parallel收集器基本相同,不同的一點是這個垃圾收集器可以兼容CMS收集器,年輕代使用ParallelNew收集器,老年代使用CMS收集器。
新生代使用復制算法,老年代使用標記-整理算法。
可以使用-XX:+UseParNewGC指定使用這個垃圾收集器。
?2.4 CMS收集器
CMS收集器(Concurrent Mark Sweep,并發(fā)標記清除)。
1.初始標記:暫停所有工作線程STW,然后標記Gc roots引用的直接對象。
? ? ? ? 直接對象:局部變量引用的new對象,靜態(tài)變量引用的new對象等。
? ? ? ? 這一步STW的目的是為了防止用戶線程產生大量的直接對象。
2.并發(fā)標記:使用多線程來垃圾回收,這一步不停止用戶線程,為了用戶體驗更好一些,初始標記很快,并發(fā)標記也不停止。可能導致對象狀態(tài)改變。
3.重新標記:主要為了修復并發(fā)標記過程中可能產生的對象狀態(tài)改變,主要使用了三色標記中的增量更新算法。這個過程也會STW,停頓時間大于初始標記,小于并發(fā)標記。
4.并發(fā)清理:開啟用戶線程,并發(fā)清理未被標記的區(qū)域,主要使用了三色標記算法。
5.并發(fā)重置:將三色標記的狀態(tài)還原,用于下一次垃圾回收標記。?
主要使用標記清除算法。
面試問題:并發(fā)清理中的浮動垃圾可以處理嗎?不可以,這次產生的浮動垃圾只能等待下一次Full GC才能回收。
標記清除的算法會導致大量空間碎片產生,可以通過開啟-XX:+UseCMSCompactAtFullCollection可以讓jvm在做完并發(fā)清理以后再做整理。
Concurrent Mode Fail:在并發(fā)標記過程有用戶線程有大量大對象產生,在FullGC時老年代無法清理出足夠的內存用來存儲大對象,此時會進入STW,CMS會切換為Serail OLD來清理老年代的內存,此時會變得很慢很慢。
CMS的相關核心參數(shù)1. -XX:+UseConcMarkSweepGC:啟用cms2. -XX:ConcGCThreads:并發(fā)的GC線程數(shù)3. -XX:+UseCMSCompactAtFullCollection:FullGC之后做壓縮整理(減少碎片)4. -XX:CMSFullGCsBeforeCompaction:多少次FullGC之后壓縮一次,默認是0,代表每次FullGC后都會壓縮一次5. -XX:CMSInitiatingOccupancyFraction: 當老年代使用達到該比例時會觸發(fā)FullGC(默認是92,這是百分比)6. -XX:+UseCMSInitiatingOccupancyOnly:只使用設定的回收閾值(-XX:CMSInitiatingOccupancyFraction設定的值),如果不指定,JVM僅在第一次使用設定值,后續(xù)則會自動調整7. -XX:+CMSScavengeBeforeRemark:在CMS GC前啟動一次minor gc,目的在于減少老年代對年輕代的引用,降低CMS GC的標記階段時的開銷,一般CMS的GC耗時 80%都在標記階段8. -XX:+CMSParallellnitialMarkEnabled:表示在初始標記的時候多線程執(zhí)行,縮短STW9. -XX:+CMSParallelRemarkEnabled:在重新標記的時候多線程執(zhí)行,縮短STW;
?
3.電商系統(tǒng)優(yōu)化JVM參數(shù)設置
電商系統(tǒng)如果JVM內存在4-6G使用ParNew(新生代)+CMS(老年代),如果大于8G推薦使用G1
ParNew+CMSJVM調優(yōu)例子,8G的內存分配4G給JVM,參數(shù)如下,按照順序 堆初始內存;堆最大內存 ;年輕代大小;桟線程大小;元空間初始值;元空間最大初始值 ;年輕代三個區(qū)域比例(Eden:S0:S1)=8:1:1 ;年輕代分代年齡(minor GC次數(shù));大對象;年輕代ParNew;老年代CMS;老年代92%的時候發(fā)生FullGC;標記整理后碎片整理;多少次FullGC以后發(fā)生碎片整理,默認0,一次FullGC就碎片整理,一般推薦配置個3也沒什么問題表示4次FullGC以后發(fā)生碎片整理
‐ Xms3072M ‐ Xmx3072M ‐ Xmn2048M ‐ Xss1M ‐ XX : MetaspaceSize = 256 M ‐ XX : MaxMetaspaceSize = 256 M ‐ XX : SurvivorRatio = 8?‐ XX : MaxTenuringThreshold = 5 ‐ XX : PretenureSizeThreshold = 1 M‐ XX : + UseParNewGC ‐ XX : + UseConcMarkSweepGC‐ XX : CMSInitiatingOccupancyFraction = 92 ‐ XX : + UseCMSCompactAtFullCollection ‐ XX : CMSFullGCsBeforeCompaction = 0
4. 三色標記原理
三色標記:將對象的狀態(tài)分為白色,灰色,黑色。
從GC roots開始查找所有引用對象路徑,如果已經分析過的直接引用對象由白色改為黑色。
如果黑色引用的對象還有沒分析完的對象改為灰色
如果灰色引用的對象被標記過,沒有其他對象引用變?yōu)楹谏F渌麤]有被分析到的對象還是白色。
引用關系見下圖。
三色標記的問題:
漏標的解決方法:增量更新和STAB,
STAB很好理解,灰色對象回收白色對象時記錄下來,下一次標記的時候重新標記一次。下一次掃描結束以后以灰色為節(jié)點重新掃描一次,白色節(jié)點置為黑色。
增量更新:黑色插入白色標記時記錄下來,下一次標記時以黑色對象為跟把這個關系重新掃描一遍。相當于將黑色對象當作灰色對象。
寫屏障偽代碼實現(xiàn)
void update(int field,int newVlue){
? ? ? ? //寫前屏障
? ? ? ? field = newVlue;
? ? ? ? //寫后屏障
}
并發(fā)標記對漏標的解決方案:
CMS:使用寫屏障+增量更新實現(xiàn)
G1,shenandoah:使用寫屏障+STAB實現(xiàn)
ZGC:讀屏障
?
?
class A{
private B b = new B();
}
class B{
private C c = new C();
private D d = new D();
}
class C{
}
class D{
}
原文鏈接:https://blog.csdn.net/qq_21575929/article/details/124330633
- 上一篇:垃圾收集器G1&ZGC詳解
- 下一篇:JVM內存模型深度剖析與優(yōu)化
相關推薦
- 2022-04-20 C#9.0推出的4個新特性介紹_C#教程
- 2022-11-06 python?基本結構語句(函數(shù)和模塊)_python
- 2022-08-13 DHCP服務簡介及Linux配置實例
- 2022-05-12 Android 記錄build打包的時間并顯示到手機上面
- 2022-06-30 python神經網絡MobileNet模型的復現(xiàn)詳解_python
- 2022-11-30 React18?中的?Suspense?API使用實例詳解_React
- 2022-09-16 Android12四大組件之Activity生命周期變化詳解_Android
- 2022-07-21 nginx的配置優(yōu)化及經常使用的超時配置說明
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支