jvm 垃圾收集算法_JVM垃圾收集和优化
jvm 垃圾收集算法
總覽
在對系統(tǒng)進(jìn)行性能相關(guān)問題的故障排除時,內(nèi)存優(yōu)化是一個需要深入分析每個系統(tǒng)在內(nèi)存中存儲的內(nèi)容,存儲時間和訪問方式的場所。 這篇文章是要對背景信息進(jìn)行注釋,并在此工作中要注意一些要點,這些工作要針對基于Java的實現(xiàn),因為深入了解JVM行為在此過程中非常有益。
Java語言在很大程度上照顧了內(nèi)存管理,從而將精力集中在其余邏輯上,從而為開發(fā)人員提供了極大的便利。 仍然對Java如何做到這一點有很好的了解,合理化我們在Java實現(xiàn)中遵循的幾種最佳實踐,并幫助更好地設(shè)計程序,并認(rèn)真思考某些方面,從長遠(yuǎn)來看,這些方面以后可能導(dǎo)致內(nèi)存泄漏和系統(tǒng)穩(wěn)定性。 Java Garbage Collector在這方面起著重要作用,它負(fù)責(zé)通過刪除內(nèi)存垃圾來釋放內(nèi)存。
這些信息可廣泛獲得,但是我在這里匯總以供參考。 :)
JVM使Java代碼能夠以獨立于硬件和OS的方式運行。 它在操作系統(tǒng)為物理機的另一抽象而分配給自己的進(jìn)程的內(nèi)存位置上運行。
JVM可以基于[1]中發(fā)布??的開放標(biāo)準(zhǔn)來實現(xiàn),眾所周知的實現(xiàn)是Oracle Hotspot JVM,幾乎與Android OS中使用的開放源代碼版本OpenJDK,IBM J9,JRockit和Dalvik VM有所不同。
簡而言之,JVM使用從平臺分配給它的資源來加載和執(zhí)行已編譯的Java字節(jié)代碼,它在上面運行。
類加載器
將字節(jié)碼加載到JVM內(nèi)存中(加載,鏈接(驗證,準(zhǔn)備,解決–>如果發(fā)出失敗的NoClassDef發(fā)現(xiàn)異常),初始化),引導(dǎo)類加載器,擴展類加載器,應(yīng)用程序類加載器
內(nèi)存和運行時數(shù)據(jù)區(qū)
盡管它并不全面,但它涵蓋了以下幾個重要部分。
- 本機方法堆棧– Java本機庫堆棧,它與平臺有關(guān),主要是用C語言編寫的。
- JVM堆棧(每個線程保留當(dāng)前執(zhí)行的方法堆棧跟蹤。如果未設(shè)置適當(dāng)?shù)闹袛?#xff0c;則遞歸方法調(diào)用可能導(dǎo)致堆棧被填充和溢出(java.lang.StackOverFlowError) 。-Xss JVM選項允許配置堆棧大小。),PC寄存器(程序計數(shù)器,指向每個線程要執(zhí)行的下一條指令。)
- 方法區(qū)域(存儲類數(shù)據(jù),大小受XX:MaxPermSize限制 ,PermGen空間默認(rèn)為64MB,如果要服務(wù)于加載數(shù)百萬個類的大型服務(wù)器應(yīng)用程序,則可以通過增加調(diào)整來避免OOM問題:PermGen空間。來自Java 8)以后,盡管允許對其進(jìn)行微調(diào)和限制,但默認(rèn)情況下,在Java8中,此PermGen空間被稱為無限制的Metaspace,沒有限制),Heap(Xms,Xmx),運行時常量池
執(zhí)行引擎
該引擎執(zhí)行通過類加載器分配給運行時數(shù)據(jù)區(qū)域的字節(jié)碼。 它利用解釋器,垃圾收集器,熱點分析器,JIT編譯器來優(yōu)化程序執(zhí)行。
有關(guān)JVM體系結(jié)構(gòu)的更多詳細(xì)信息,請參見[2]。
現(xiàn)在我們知道了垃圾收集器在JVM體系結(jié)構(gòu)中的位置。 讓我們深入了解內(nèi)部。
垃圾收集器
這是Java自動內(nèi)存管理過程,它刪除了不再使用的對象。 接下來的問題是,它如何決定是否使用該對象。
它定義了兩類對象,
活動對象 –從另一個對象引用的可訪問對象。 最終,參考鏈接將到達(dá)根,該根是創(chuàng)建整個對象圖的主線程。 死對象 –只是躺在堆中的其他對象未引用的不可訪問對象。
此分類和垃圾回收基于以下兩個事實。
1.大多數(shù)對象在創(chuàng)建后很快就變得無法訪問。 通常,短暫對象僅存在于方法上下文中。 2.老物件很少指年輕物件。 例如,壽命長的緩存幾乎不會從中引用較新的對象。
新創(chuàng)建的對象實例駐留在Java堆中,該堆可以進(jìn)行不同的生成,如下所示。 垃圾收集是通過稱為“垃圾收集器”的守護程序線程完成的,該線程將對象引導(dǎo)通過堆中的不同空間。
垃圾收集分3個步驟進(jìn)行。
1.標(biāo)記 –從根開始并遍歷對象圖,將可到達(dá)的對象標(biāo)記為活動對象。
2.掃描 –刪除未標(biāo)記的對象。 3.緊湊 –對內(nèi)存進(jìn)行碎片整理,使活動對象的分配連續(xù)。 這被認(rèn)為是最耗時的過程。
堆區(qū)域劃分如下。
舊的(終身使用的)代 –可以存活很長時間的對象,請留在這里,直到它被標(biāo)記為無法訪問并在遍及整個堆的主要垃圾收集中清理為止。
年輕一代 –進(jìn)一步分為3個伊甸園空間和2個幸存者空間。 垃圾收集分為兩個階段:“次要”或“主要”。 這兩個垃圾回收都是停止運行的操作,它們停止所有其他內(nèi)存訪問。 應(yīng)用程序可能不會感覺到次要GC,因為它僅掃描年輕一代空間會很小。
垃圾收集器
內(nèi)存生命周期如下圖所示,如上圖所示。
1.新創(chuàng)建的對象駐留在Eden空間中。 (就像人類從伊甸園開始的一樣:)在伊甸園空間變滿之前,它一直在不斷增加新的物體。
2.當(dāng)Eden空間已滿時,將運行一個次要GC,標(biāo)記活動對象,然后將這些活動對象移至“幸存者從”空間,然后掃掠空閑的Eden空間。
3.然后在程序運行時繼續(xù)用新對象填充Eden空間。 現(xiàn)在,當(dāng)Eden空間已滿時,我們先前也已將“幸存者來自”空間中的對象移動了。 次要GC在這兩個空間中運行標(biāo)記對象,然后將剩余的活動對象整體移至其他幸存者空間。 想知道為什么不將有生命的物體從伊甸園空間復(fù)制到“幸存者從”的剩余空間,而不是全部轉(zhuǎn)移到另一個幸存者空間? 好吧,事實證明,在緊湊的步驟中,將所有對象移到另一個對象上要比壓縮其中包含對象的區(qū)域更為有效。
4.此循環(huán)將在幸存者空間之間重復(fù)移動對象,直到達(dá)到配置的閾值(-XX: MaxTenuringThreshold ) 。 (它跟蹤每個對象生存了多少個GC循環(huán))。 當(dāng)達(dá)到閾值時,這些對象將被移至保管空間。
5.隨著時間的流逝,如果使用權(quán)空間也被填滿,則主GC將啟動并遍歷整個堆內(nèi)存空間,以執(zhí)行GC步驟。 這種暫停可以在人際互動中感受到,這是不希望的。
當(dāng)內(nèi)存泄漏或長時間駐留大量高速緩存時,使用期限將被占用。 在這種情況下,這些對象甚至可能沒有被檢測為死亡。 這會導(dǎo)致主要GC頻繁運行,因為它檢測到永久性空間已滿,但是由于無法清除任何內(nèi)容,因此無法清理足夠的內(nèi)存。
當(dāng)內(nèi)存不足時,日志中的錯誤“ java.lang.OutOfMemoryError”將清楚地提示我們。 另外,如果我們看到頻繁使用大量內(nèi)存而導(dǎo)致CPU頻繁運行,則可能是由于某些內(nèi)存處理問題需要引起注意而導(dǎo)致GC頻繁運行的征兆。
當(dāng)專注于JVM的微調(diào)(關(guān)注內(nèi)存的利用率)時,主要的決定因素是響應(yīng)性/延遲和吞吐量中更關(guān)鍵的因素。 如果在批處理中吞吐量是最重要的,那么如果可以提高總體吞吐量,我們可以在運行主要GC的過程中稍作停頓。 因為應(yīng)用程序偶爾的響應(yīng)速度可能不是那里的問題。
另一方面,如果像在基于UI的應(yīng)用程序中一樣,響應(yīng)性至關(guān)重要,則應(yīng)嘗試避免使用大型GC。 也就是說,這樣做并沒有幫助。 例如,我們可以通過增加年輕一代的空間來延遲大型GC。 但是隨后,小型GC將開始花費大量時間,因為它現(xiàn)在需要遍歷并壓縮巨大的空間。 因此,要擁有正確的尺寸,就需要謹(jǐn)慎地實現(xiàn)年輕人和老年人之間的正確比例。 有時,這甚至可以進(jìn)入應(yīng)用程序設(shè)計細(xì)節(jié)中,以通過對象創(chuàng)建模式和緩存位置來微調(diào)內(nèi)存使用情況。 這將是另一篇文章的主題,該文章分析堆轉(zhuǎn)儲和火焰圖,以確定要緩存的最佳內(nèi)容。
垃圾收集器
由于垃圾回收的作用對應(yīng)用程序的性能有很大的影響,因此工程師已經(jīng)投入了大量的精力來改進(jìn)它。 結(jié)果是,我們可以根據(jù)需求選擇最佳垃圾收集器。 以下是不完整的選項列表。
1.串行收集器
在單個線程中運行。 僅適用于基本應(yīng)用。
一個線程執(zhí)行垃圾回收。 它只會使世界處于標(biāo)記和重新標(biāo)記階段。 其余的工作在應(yīng)用程序運行時完成,并且不等待舊的版本已滿。 當(dāng)內(nèi)存空間很大,有大量的CPU來滿足并發(fā)執(zhí)行時,以及當(dāng)應(yīng)用程序要求最短的暫停和響應(yīng)時間成為關(guān)鍵因素時,這是一個不錯的選擇。 過去,這是大多數(shù)Web應(yīng)用程序中最受歡迎的。
3.并行收集器
該收集器使用多個CPU。 它等待舊的一代充滿或接近充滿,但是當(dāng)它運行時,它停止了世界。 多個線程進(jìn)行標(biāo)記,清除和壓縮,使垃圾收集更快。 當(dāng)內(nèi)存不是很大并且CPU數(shù)量受到限制時,這是一個很好的選擇,可以滿足對吞吐量的要求,可以承受暫停。
4. G1(垃圾優(yōu)先)收集器(1.7以上)
通過允許配置(例如,GC運行時暫停時間),此選項可提高垃圾收集的可預(yù)測性。 據(jù)說在并行性和并發(fā)性兩方面都具有優(yōu)勢。 它將內(nèi)存劃分為多個區(qū)域,每個區(qū)域都被視為伊甸園,幸存者或保有權(quán)空間。 如果該區(qū)域有更多無法訪問的對象,則該區(qū)域?qū)⑹紫缺焕厥铡?
版本中的默認(rèn)垃圾收集器
- Java 7 –并行GC
- Java 8 –并行GC
- Java 9 – G1 GC
- Java 10 – G1 GC
- Java 11 – G1 GC(ZGC與Epsilon一起作為實驗功能提供)
- Java 12 – G1 GC(引入了Shenandoah GC。僅適用于OpenJDK。)
垃圾收集器的優(yōu)化參數(shù)
除非有默認(rèn)設(shè)置要解決的問題,或者是經(jīng)過長時間的考慮,并且經(jīng)過長時間的生產(chǎn)級別的負(fù)載模式驗證之后,才決定要調(diào)整JVM,否則不要這樣做。 這是因為Java Ergonomics已經(jīng)取得了很大進(jìn)步,并且如果應(yīng)用程序的外觀不丑陋,則大多數(shù)時候?qū)⒛軌驁?zhí)行許多優(yōu)化。 可以在[5]中找到選項的完整列表,包括配置堆空間的大小,閾值,要使用的垃圾收集器的類型等。
診斷
除堆轉(zhuǎn)儲外,以下配置還有助于通過GC行為診斷內(nèi)存問題。
-XX:-PrintGCDetails –打印垃圾收集的詳細(xì)信息。
-Xloggc:<文件名> –將GC日志記錄詳細(xì)信息打印到給定文件。
-XX:-UseGCLogFileRotation –完成上述配置后,啟用GC日志文件旋轉(zhuǎn)。 -XX:-HeapDumpOnOutOfMemoryError –如果發(fā)生OOM錯誤,則轉(zhuǎn)儲堆內(nèi)容以進(jìn)行進(jìn)一步分析。 -XX:OnOutOfMemoryError =” <cmd args =””>; <cmd args =””>” –如果發(fā)生OOM錯誤,則要運行的命令集。 遇到錯誤時允許執(zhí)行任何自定義任務(wù)。
我們將在另一篇文章中討論診斷和分析細(xì)節(jié)。
干杯!
[1] – https://docs.oracle.com/javase/specs/index.html
[2] – https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.6
[2] – Oracle垃圾收集調(diào)優(yōu)指南–
https://docs.oracle.com/javase/9??/gctuning/ergonomics.htm#JSGCT-GUID-DB4CAE94-2041-4A16-90EC-6AE3D91EC1F1
[3] –新的Java垃圾收集器–
https://blogs.oracle.com/javamagazine/understanding-the-jdks-new-superfast-garbage-collectors
[4] –可用的收藏家–
https://docs.oracle.com/cn/java/javase/13/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C
[5] – JVM選項–
https://www.oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html
翻譯自: https://www.javacodegeeks.com/2020/05/jvm-garbage-collection-and-optimizations.html
jvm 垃圾收集算法
總結(jié)
以上是生活随笔為你收集整理的jvm 垃圾收集算法_JVM垃圾收集和优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 爱玛电动车全部车型号及图片(盘点受欢迎爱
- 下一篇: 贵港市属于哪个省(来广西贵港旅游必去的5