柚子快報邀請碼778899分享:JVM知識點總結(jié)
柚子快報邀請碼778899分享:JVM知識點總結(jié)
一、JVM結(jié)構(gòu)
類加載子系統(tǒng)
JVM類加載器分為3層,啟動類加載器(Bootstrap類加載器),加載%JAVA_HOME%/lib包下的核心類;擴(kuò)展類加載器(Extension類加載器) ,加載%JAVA_HOME%/lib/ext內(nèi)的擴(kuò)展類;應(yīng)用類加載器(Application類加載器),加載應(yīng)用程序內(nèi)定義的類。雙親委派(類加載機(jī)制):①應(yīng)用類加載器收到加載類的請求時,會先檢查自己是否加載過這個類,加載過則直接返回;②如果未加載過則委托它的父級-擴(kuò)展類加載器加載,擴(kuò)展類加載器已加載,則返回該類,加載結(jié)束;③如果擴(kuò)展類加載器仍未加載,則繼續(xù)向上委派,由啟動類加載器加載,啟動類加載器已加載,則返回該類,加載結(jié)束④雙親都無法完成加載,則由應(yīng)用類加載器嘗試加載該類。優(yōu)點:①保護(hù)核心類;②避免重復(fù)加載。 執(zhí)行引擎運行時數(shù)據(jù)區(qū) 運行時數(shù)據(jù)區(qū)包含:
線程共享區(qū)域:
堆區(qū): 動態(tài)擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)。堆區(qū)特點: ①線程共享,需要考慮并發(fā)問題 ②動態(tài)擴(kuò)展的內(nèi)存區(qū)域; ③被垃圾回收器監(jiān)控回收; ④存儲的對象都有一個指向它的類引用指針; ⑤分為年輕代和老年代,年輕代又分為Eden和兩個Survivor(幸存者)區(qū)域,默認(rèn)比例:8:1:1; ⑥按照對象創(chuàng)建的時間順序分配內(nèi)存,標(biāo)記清除算法回收垃圾會產(chǎn)生大量內(nèi)存碎片導(dǎo)致頻繁GC。方法區(qū): Java8之前通過永久代實現(xiàn),使用堆內(nèi)存,大小有限,無法動態(tài)調(diào)整,加載類過多或動態(tài)生成類過多時容易OOM;Java8使用元空間實現(xiàn),使用堆外內(nèi)存,可動態(tài)調(diào)整,避免了永久代的一些問題。直接內(nèi)存區(qū)域: 由操作系統(tǒng)直接操作的內(nèi)存區(qū)域。優(yōu)點:①零拷貝提高效率②不歸Java堆內(nèi)存管理,降低GC壓力。缺點:①不歸Java堆內(nèi)存管理,容易內(nèi)存泄漏,要注意釋放②直接內(nèi)存的分配和釋放比Java堆上的操作成本更高。 線程私有區(qū)域:
程序計數(shù)器: 記錄當(dāng)前線程執(zhí)行到的位置,線程切換需要使用。虛擬機(jī)棧: 用于存儲方法調(diào)用和局部變量。棧幀: 局部變量表、幀數(shù)據(jù)區(qū)、操作數(shù)棧、動態(tài)鏈接。本地方法棧: native方法的方法調(diào)用和局部變量。
二、 如何判斷對象是否存活
引用計數(shù)法: 引用一次計數(shù)+1,簡單快速,但出現(xiàn)互相引用時會導(dǎo)致無法回收。可達(dá)性分析法: 以GC Roots為起點,開始向下遍歷,能夠被訪問到的對象認(rèn)為是存活的,無法到達(dá)的對象認(rèn)為垃圾對象等待回收。 GC Roots:①靜態(tài)變量②常量③虛擬機(jī)棧引用的對象④本地方法棧引用的對象。
三、垃圾回收算法
標(biāo)記復(fù)制: 使用雙倍內(nèi)存,將存活對象移動到另一內(nèi)存區(qū)域,未存活對象回收,然后交換區(qū)域。特點:速率快,使用內(nèi)存只有總內(nèi)存的一半,常用于年輕代垃圾回收。標(biāo)記清除: 標(biāo)記后直接回收未存活對象,會產(chǎn)生大量內(nèi)存碎片,導(dǎo)致頻繁GC。速率中等,常用于老年代垃圾回收。標(biāo)記整理: 過程:①標(biāo)記階段:從GCRoots出發(fā)標(biāo)記存活對象;②整理階段:將存活對象移動到一端,同時清理未標(biāo)記的數(shù)據(jù);③更新引用:更新存活對象引用,使其指向?qū)ο笏谛挛恢玫牡刂?;④回收階段:回收掉所有未被標(biāo)記的對象,釋放內(nèi)存(整理階段的回收可能存在遺漏,如錯標(biāo),所以需要回收階段再統(tǒng)一回收)。速率慢,減少內(nèi)存碎片,減少內(nèi)存分配失敗的情況(內(nèi)存連續(xù))。
四、三色標(biāo)記法
將對象標(biāo)記為三種顏色:白色、灰色和黑色,用于表示對象的可達(dá)性狀態(tài)。
白色:所有對象初始狀態(tài)都為白色,表示尚未被訪問和處理?;疑簩ο蟊粯?biāo)為灰色表示這些對象已經(jīng)訪問,但是其引用的對象還未被遍歷。黑色:對象被標(biāo)記為黑色表示這些對象已經(jīng)被訪問,并且其引用的對象已經(jīng)被遍歷。
基本流程: ①初始化:根對象標(biāo)記為灰色,其他對象標(biāo)記為白色; ②標(biāo)記階段:從根對象開始遍歷對象,遍歷完成的對象標(biāo)記為黑色; ③清除階段:清除所有未被標(biāo)記為黑色的對象,這些對象被認(rèn)為不可達(dá),可以回收。
五、四大引用類型
強(qiáng)引用: 即使系統(tǒng)內(nèi)存不足,垃圾回收時也不會回收該對象,如new的對象。軟引用: 系統(tǒng)內(nèi)存充足,垃圾回收時不會被回收,系統(tǒng)內(nèi)存不足時會被回收,適合緩存功能。弱引用: 系統(tǒng)內(nèi)存無論是否充足,垃圾回收時都會被回收,ThreadLocal 中 Key。虛引用: 相當(dāng)于不存在,垃圾回收時會得到通知。
六、yangGC流程
yangGC發(fā)生在年輕代,年輕代區(qū)域分為1個Eden區(qū)和兩個幸存區(qū)(Survivor),比例8:1:1,幸存區(qū)分為from/to兩個角色;Eden區(qū)三色標(biāo)記法判斷對象存活,然后通過標(biāo)記復(fù)制算法垃圾回收,Eden區(qū)存活對象移動到to區(qū)域;From區(qū)域存儲的上一次yangGC存活的對象,根據(jù)存活對象的存活年代判斷是否移動到老年代,未移動到老年代的對象移動到To區(qū)域;交換From和To區(qū)域的引用,保證To區(qū)域GC完成后為空;yangGC完成后如果新創(chuàng)建對象需要的內(nèi)存仍不夠,會觸發(fā)空間擔(dān)保機(jī)制將存活對象從新生代晉升到老年代;循環(huán)上述過程,To區(qū)域被填滿后所有對象移動到老年代。
七、主流垃圾回收算法
CMS: 特點:基于標(biāo)記清除算法,并發(fā)收集、低停頓。在Java 9及更高版本中,CMS已經(jīng)被標(biāo)記為廢棄。工作機(jī)制: ①初始標(biāo)記:標(biāo)記GC Roots直接關(guān)聯(lián)的對象,速度很快,需要暫停所有工作線程; ②并發(fā)標(biāo)記:遍歷GC Roots引用鏈,并發(fā)進(jìn)行,不需要暫停工作線程; ③重新標(biāo)記:修正并發(fā)標(biāo)記期間,因用戶線程繼續(xù)工作而導(dǎo)致產(chǎn)生變動的一部分對象的標(biāo)記記錄,需要暫停所有工作線程; ④并發(fā)清除:清除遍歷GC Roots不可達(dá)的對象,并發(fā)進(jìn)行,不需要暫停工作線程。Parallel: :多線程垃圾回收器,基于標(biāo)記整理算法,適用多核處理器和對吞吐量要求較高的場景。Java8默認(rèn)的垃圾回收器。G1: JDK9之后默認(rèn)的垃圾回收器,基于標(biāo)記整理算法。旨在提供比CMS更好的性能,特別是在大內(nèi)存系統(tǒng)上,同時也解決了CMS的一些問題,如內(nèi)存碎片問題。CMS與Parallel區(qū)別: ①使用場景不同,CMS適合對停頓時間要求較高的場景,Parallel適合對吞吐量要求較高的場景; ②工作原理不同,CMS 老年代垃圾回收,基于標(biāo)記清除算法,會產(chǎn)生內(nèi)存碎片導(dǎo)致頻繁GC,Parallel 老年代垃圾回收,基于標(biāo)記整理算法,不會產(chǎn)生大量內(nèi)存碎片; ③CMS停頓時間較短,Parallel停頓時間較長,停頓時無法正常提供服務(wù)。
八、OOM
產(chǎn)生的原因: ①堆區(qū)分配的內(nèi)存不足; ②堆區(qū)內(nèi)存泄漏,多余內(nèi)存無法正常釋放,代碼有問題; ③棧內(nèi)存不足,虛擬機(jī)在擴(kuò)展棧的時候無法申請到足夠的內(nèi)存; StackOverflowError :線程請求的棧深度超過了虛擬機(jī)允許的最大深度,會拋出該異常(無限遞歸)。
九、常用工具
jps:輸出當(dāng)前系統(tǒng)中正在運行的java進(jìn)程的進(jìn)程ID及狀態(tài)信息。 jstack:生成java進(jìn)程的線程轉(zhuǎn)儲信息,可以獲取 Java 進(jìn)程中每個線程的堆棧跟蹤信息,包括線程的狀態(tài)、調(diào)用棧信息、鎖信息等。 jstat:虛擬機(jī)統(tǒng)計信息監(jiān)控工具。 jinfo:實時查看和調(diào)整虛擬機(jī)的各項參數(shù)。 jmap:生成虛擬機(jī)的內(nèi)存轉(zhuǎn)存儲快照。 JConsole:可視化監(jiān)控工具。
十、如何進(jìn)行JVM調(diào)優(yōu)
明確調(diào)優(yōu)原因;全面監(jiān)控,收集性能數(shù)據(jù),分析GC日志,涉及GC類型、頻率、停頓時間等信息;如果存在內(nèi)存泄漏,則下載dump文件,利用工具分析內(nèi)存泄漏對象關(guān)聯(lián)的GC Roots,優(yōu)化對應(yīng)代碼;根據(jù)業(yè)務(wù)場景和需求選擇合適的GC算法,如CMS、Parallel、G1等;設(shè)置JVM參數(shù),如初始堆內(nèi)存大小、最大堆內(nèi)存大小、新生代大小等;優(yōu)化代碼;根據(jù)需求,壓測應(yīng)用,觀察吞吐量、性能、GC頻率、內(nèi)存大小、GC時間等,不斷調(diào)整JVM參數(shù)到合適值,確保調(diào)優(yōu)后達(dá)到性能和穩(wěn)定性要求。
一般情況下,yangGC單次小于50ms且間隔在10s以上,表示健康; FullGC單次小于1s,且間隔在10min以上,表示健康。調(diào)優(yōu)參數(shù):
-Xmx 最大堆內(nèi)存-Xms 初始堆內(nèi)存-Xmn 新生代大小-XX:MetaSpaceSize:初始元空間大小-XX:MaxMetaSpaceSize:最大元空間大小-XX:MaxDirectMemorySize:最大堆外內(nèi)存-XX:+HeapDumpOnOutOfMemoryError: 內(nèi)存溢出時生成快照文件-XX:HeapDumpPath: 內(nèi)存溢出時生成快照文件的路徑
柚子快報邀請碼778899分享:JVM知識點總結(jié)
相關(guān)閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。