最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

JVM 垃圾收集器全面剖析:算法、實現(xiàn)和優(yōu)化

2023-06-05 16:33 作者:politmirror  | 我要投稿

JVM 的一個重要組件是垃圾收集器(GC,Garbage Collector)。垃圾收集器負(fù)責(zé)自動管理 Java 應(yīng)用程序中的內(nèi)存資源,以確保程序能夠在充足的內(nèi)存中運行

垃圾收集算法

垃圾收集算法主要用于判斷對象是否還在使用,以及如何釋放不再使用的對象所占用的內(nèi)存。常見的垃圾收集算法包括

標(biāo)記-清除算法(Mark-Sweep)

首先,將所有對象分為兩類,一類是可達(dá)對象,指的是從根節(jié)點(例如局部變量、靜態(tài)變量等)通過引用鏈可以訪問到的對象;另一類是不可達(dá)對象,指的是無法通過根節(jié)點訪問到的對象。標(biāo)記-清除算法首先將所有可達(dá)對象進(jìn)行標(biāo)記,然后對標(biāo)記的對象進(jìn)行清除。


標(biāo)記-清除算法分為兩個階段:標(biāo)記階段和清除階段。


在標(biāo)記階段,垃圾收集器從根節(jié)點(如局部變量、靜態(tài)變量等)出發(fā),遍歷所有可達(dá)對象(即從根節(jié)點通過引用鏈可以訪問到的對象),并將這些對象進(jìn)行標(biāo)記。在實際實現(xiàn)中,標(biāo)記可以通過在對象頭中設(shè)置一個標(biāo)志位來實現(xiàn)。


標(biāo)記階段完成后,進(jìn)入清除階段。清除階段會遍歷整個堆空間,釋放未被標(biāo)記的對象所占用的內(nèi)存。這樣,不再使用的對象所占用的內(nèi)存就被回收了。

復(fù)制算法(Copying)

復(fù)制算法將內(nèi)存分為兩個相等的區(qū)域,同時只使用一個區(qū)域。當(dāng)垃圾收集開始時,遍歷所有可達(dá)對象,并將這些對象及其引用復(fù)制到另一個區(qū)域中。然后丟棄原區(qū)域的所有內(nèi)容,將內(nèi)存指針指向新的區(qū)域。這樣,新區(qū)域中的內(nèi)存就不再有碎片,可以提高內(nèi)存分配效率。


復(fù)制算法主要解決了標(biāo)記-清除算法中的內(nèi)存碎片問題。復(fù)制算法將內(nèi)存空間劃分為兩個相等的區(qū)域 A 和 B(例如,半?yún)^(qū)),同時只使用一個區(qū)域(例如區(qū)域 A)來存儲對象。當(dāng)垃圾收集開始時,垃圾收集器遍歷所有可達(dá)對象,并將這些對象及其引用復(fù)制到另一個區(qū)域(例如區(qū)域 B)中。接著,清空區(qū)域 A 的所有內(nèi)容,將內(nèi)存指針指向區(qū)域 B。因此,活動對象被復(fù)制到新的區(qū)域后,內(nèi)存空間變?yōu)檫B續(xù)的。


復(fù)制算法的主要問題是效率低下,因為需要將所有可達(dá)對象復(fù)制到新的內(nèi)存區(qū)域,而且內(nèi)存的一半空間始終是空閑的。


標(biāo)記-整理算法(Mark-Compact)

標(biāo)記-整理算法結(jié)合了標(biāo)記-清除和復(fù)制算法的優(yōu)點,主要用于解決老年代的垃圾收集問題。


首先,在標(biāo)記階段,垃圾收集器和標(biāo)記-清除算法一樣,從根節(jié)點開始遍歷所有可達(dá)對象并進(jìn)行標(biāo)記。


接下來,在整理階段,將所有被標(biāo)記的對象向一端靠攏,并丟棄所有未標(biāo)記的對象。這樣一來,內(nèi)存空間會變得連續(xù),并消除了碎片問題。


標(biāo)記-整理算法的主要優(yōu)點是避免了復(fù)制算法中的空間浪費問題。但是,標(biāo)記-整理算法在整理階段需要移動對象,因此可能會導(dǎo)致一定的性能損耗。


垃圾收集器實現(xiàn)

Serial 收集器

Serial 收集器是一個單線程收集器,它在垃圾收集時,只使用一個線程去執(zhí)行收集操作。在執(zhí)行垃圾收集任務(wù)時,需要暫停其他所有的工作線程(稱為 Stop-The-World,簡稱 STW),直到垃圾收集完成。


Serial 收集器適用于對內(nèi)存和 CPU 資源有限的場景,以及客戶端應(yīng)用程序。由于它是單線程的,因此 Serial 收集器在多核處理器環(huán)境下相對效率較低。


Serial 收集器使用標(biāo)記-復(fù)制算法進(jìn)行新生代收集(Minor GC),使用標(biāo)記-整理算法進(jìn)行老年代收集(Major GC 或 Full GC)。

Parallel(Throughput)收集器

Parallel 收集器(也稱為吞吐量收集器)是一個并行收集器。與 Serial 收集器不同,Parallel 收集器使用多個線程同時執(zhí)行垃圾收集任務(wù),這在多核處理器環(huán)境下可以高效利用 CPU 資源,從而提高垃圾收集的效率。


Parallel 收集器主要目標(biāo)是提高系統(tǒng)的吞吐量。它默認(rèn)情況下會盡量利用可用的 CPU 核心來加速垃圾收集操作。類似于 Serial 收集器,Parallel 收集器在垃圾收集期間也需要暫停其他所有工作線程。


Parallel 收集器同樣使用標(biāo)記-復(fù)制算法進(jìn)行新生代收集,使用標(biāo)記-整理算法進(jìn)行老年代收集。

CMS(Concurrent Mark Sweep)收集器

CMS 收集器是一種以降低停頓時間為目標(biāo)的收集器。與 Serial 和 Parallel 收集器不同,CMS 收集器在執(zhí)行垃圾收集任務(wù)時,并不需要暫停所有工作線程。CMS 收集器通過并發(fā)標(biāo)記-清除算法實現(xiàn),其核心思想是將垃圾收集過程中的一部分工作與應(yīng)用線程并發(fā)執(zhí)行,從而減少單次垃圾收集引起的暫停時間。


CMS 收集器的垃圾收集過程主要分為下面幾個階段:

  • 初始標(biāo)記(Initial Mark,需要 STW):標(biāo)記與根節(jié)點直接關(guān)聯(lián)的對象

  • 并發(fā)標(biāo)記(Concurrent Mark):處理應(yīng)用程序并發(fā)運行時標(biāo)記可達(dá)對象

  • 重新標(biāo)記(Remark,需要 STW):修正并發(fā)標(biāo)記階段因應(yīng)用程序運行引入的新引用關(guān)系

  • 并發(fā)清除(Concurrent Sweep):清除不可達(dá)對象


CMS 收集器適用于對響應(yīng)時間有較高要求的應(yīng)用場景,比如 Web 服務(wù)器、緩存服務(wù)器等。

G1(Garbage-First)收集器

G1 收集器是一種新型的收集器,旨在替代 CMS 收集器。G1 收集器主要針對大堆內(nèi)存的應(yīng)用程序,它的主要目標(biāo)是將程序的暫停時間控制在可預(yù)測的范圍內(nèi),以便滿足較嚴(yán)格的停頓時間要求。


G1 收集器將整個 Java 堆劃分為許多連續(xù)的內(nèi)存區(qū)域(Region),這些區(qū)域大小相等且大小可配置。每個區(qū)域可以是 Eden 空間、Survivor 空間或者 Old 空間的一部分。G1 收集器通過對不同區(qū)域進(jìn)行優(yōu)先級排序,在垃圾收集時首先處理優(yōu)先級較高的區(qū)域。


G1 收集器的垃圾收集過程主要分為以下幾個階段:

  • 初始標(biāo)記(Initial Mark,需要 STW):標(biāo)記與根節(jié)點直接關(guān)聯(lián)的對象

  • 并發(fā)標(biāo)記(Concurrent Mark):處理應(yīng)用程序并發(fā)運行時標(biāo)記可達(dá)對象

  • 最終標(biāo)記(Final Mark,需要 STW):修正并發(fā)標(biāo)記階段因應(yīng)用程序運行引入的新引用關(guān)系

  • 篩選回收(Evacuation,部分需要 STW):將選定的區(qū)域中的存活對象復(fù)制到其他空閑區(qū)域,釋放回收區(qū)域的空間


G1 收集器在實現(xiàn)上使用了標(biāo)記-復(fù)制算法的變種,并引入了并發(fā)執(zhí)行和增量回收的策略。這使得 G1 能夠在保證較低的停頓時間的同時,也能實現(xiàn)較高的內(nèi)存利用率。

垃圾收集優(yōu)化策略

調(diào)整堆大小

合理地設(shè)置堆的初始大?。?Xms)和最大大?。?Xmx)可以避免頻繁的垃圾收集。一般來說,初始大小設(shè)置較小可以降低應(yīng)用啟動所需的資源,而最大大小要根據(jù)應(yīng)用程序的內(nèi)存需求進(jìn)行設(shè)置。堆大小不應(yīng)該設(shè)置過大,以免造成內(nèi)存浪費;也不應(yīng)該設(shè)置過小,避免頻繁觸發(fā)垃圾收集導(dǎo)致性能下降。

調(diào)整新生代和老年代的比例

JVM 堆內(nèi)存分為新生代(包括 Eden 空間和 Survivor 空間)和老年代,兩者的大小比例會影響垃圾收集的效率和頻率。通過-Xmn 參數(shù)設(shè)置新生代的大小,從而調(diào)整新生代和老年代的比例。

通常,新生代越大,Minor GC 的時間間隔越長,但 Full GC 的時間也相對較長。因此,需要根據(jù)應(yīng)用程序的對象生命周期特點來設(shè)置合適的新生代和老年代比例。

選擇合適的垃圾收集器

根據(jù)應(yīng)用程序的特點和需求,選擇合適的垃圾收集器。例如,對于需要低延遲的應(yīng)用程序,可以考慮使用 CMS 或 G1 收集器。對于需要高吞吐量的應(yīng)用程序,可以選擇 Parallel 收集器。對于單核處理器或內(nèi)存資源有限的場景,可以使用 Serial 收集器。

監(jiān)控和分析垃圾收集日志

監(jiān)控并分析垃圾收集日志有助于發(fā)現(xiàn)性能瓶頸、內(nèi)存泄漏或其他 GC 問題。通過查看日志,可以了解 GC 的頻率、暫停時間、收集效果等指標(biāo),從而對垃圾收集進(jìn)行優(yōu)化??梢允褂?Xloggc 參數(shù)將 GC 日志輸出到文件。

優(yōu)化程序代碼

減少不必要的對象創(chuàng)建和長生命周期對象。對于短生命周期的對象,可以盡量復(fù)用已有對象,減少創(chuàng)建新對象的開銷,降低垃圾收集頻率。例如,可以使用 StringBuilder 替代 String 進(jìn)行字符串拼接操作。

對于長生命周期的對象,避免創(chuàng)建過多的大對象。大對象容易導(dǎo)致內(nèi)存碎片問題,降低內(nèi)存使用率。合理設(shè)計數(shù)據(jù)結(jié)構(gòu),避免不必要的引用關(guān)系,可減少長生命周期對象的數(shù)量。

使用 JVM 參數(shù)進(jìn)行優(yōu)化

-XX:SurvivorRatio 設(shè)置 Eden 空間和 Survivor 空間的比例。

-XX:MaxTenuringThreshold 控制對象在 Survivor 空間的晉升閾值,達(dá)到閾值后對象將進(jìn)入老年代。

-XX:+DisableExplicitGC 禁止 System.gc()顯式調(diào)用,避免應(yīng)用程序觸發(fā)頻繁的垃圾收集。

-XX:+UseStringDeduplication 開啟 Java 8 中的字符串重復(fù)數(shù)據(jù)清理功能,減少相同字符串在內(nèi)存中的存儲。

這些策略需要根據(jù)應(yīng)用程序的具體需求進(jìn)行調(diào)整。垃圾收集優(yōu)化是一個持續(xù)的過程,需要不斷地進(jìn)行調(diào)整和優(yōu)化,才能使應(yīng)用程序在性能和資源使用方面達(dá)到最佳效果。


JVM 垃圾收集器全面剖析:算法、實現(xiàn)和優(yōu)化的評論 (共 條)

分享到微博請遵守國家法律
漠河县| 宁陵县| 新巴尔虎左旗| 抚顺县| 平顺县| 阿合奇县| 申扎县| 仪陇县| 济阳县| 白山市| 商南县| 偃师市| 游戏| 广宁县| 修水县| 海兴县| 忻城县| 赣榆县| 吕梁市| 金阳县| 闵行区| 普格县| 共和县| 常山县| 芒康县| 横山县| 伊春市| 徐汇区| 河南省| 谢通门县| 新巴尔虎右旗| 濮阳县| 宜川县| 阳泉市| 舒城县| 江油市| 洱源县| 额敏县| 香港 | 衡山县| 庄河市|