最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java中的GC收集器詳情

 更新時間:2021年10月22日 10:09:23   作者:onlythinking  
這篇文章主要介紹了java中的GC收集器,GC(Garbage collection )指的是程序內(nèi)存管理分手動和自動,手動內(nèi)存管理,需要我們編程的時候顯式分配和釋放空間,但如果忘記釋放,會造成嚴(yán)重的內(nèi)存泄漏問題,下面文章內(nèi)容我們就來實例說明情況,需要的朋友可以參考一下

1、GC(Garbage collection )

程序內(nèi)存管理分手動和自動。

手動內(nèi)存管理,需要我們編程的時候顯式分配和釋放空間,但如果忘記釋放,會造成嚴(yán)重的內(nèi)存泄漏問題。如下:

//申請40MB內(nèi)存
 int* p = malloc(1024 * 1024 * 10 * sizeof(int));
 //釋放內(nèi)存
 free(p);


顯式分配和釋放很容易就造成內(nèi)存泄漏。因此我們希望有一種能自動回收內(nèi)存的方法,這樣就可以消除人為造成的錯誤。我們將這種自動化稱為垃圾收集(簡稱GC

現(xiàn)代高級編程語言基本上都具備GC功能。

2、GC算法

GC算法按照下面兩方面內(nèi)容設(shè)計

  • 標(biāo)記出所有活動對象(程序正在使用或者叫可達(dá)對象);
  • 刪除未使用的對象和重新整理空間。

2.1標(biāo)記活動對象

java gc 通過追蹤活動對象進(jìn)行標(biāo)記,未被標(biāo)記的對象為空閑狀態(tài)??臻e狀態(tài)對象將會在清理階段被回收。

GC標(biāo)記對象是從GcRoots開始,它是一類特殊對象,分以下幾種:

  • 當(dāng)前執(zhí)行方法中的局部變量和方法參數(shù)。
  • 活動Java線程。
  • 靜態(tài)變量由其類引用。不過類本身是可以被垃圾收集,回收時將刪除所有引用的靜態(tài)變量。
  • JNI引用是本機(jī)代碼作為JNI調(diào)用的一部分創(chuàng)建的Java對象。這樣創(chuàng)建的對象將被特別對待,因為JVM不知道本機(jī)代碼是否正在引用它。

標(biāo)記開始時,GC會遍歷內(nèi)存中的整個對象樹,從那些GC Roots開始,然后是從根到其他對象(例如實例字段)的引用。GC訪問的每個對象都 標(biāo)記 為活動對象。

標(biāo)記結(jié)束后,如下圖所示,藍(lán)色表示為GCroots仍然在引用的對象,灰色表示為空閑對象等待回收。

標(biāo)記階段需要注意兩方面:

  • 標(biāo)記需要暫停應(yīng)用程序線程,這很好理解如果應(yīng)用線程一直在運(yùn)行對象活動狀態(tài)就會一直變化,GC就無法進(jìn)行標(biāo)記。這種情況稱為 安全點, 導(dǎo)致 Stop The World暫停簡述為(STW)。
  • 暫停的持續(xù)時間受活動對象的數(shù)量影響,不取決于堆的大小和對象總數(shù) 。 因此,增加堆大小不會直接影響標(biāo)記階段的持續(xù)時間。

2.2 刪除空閑對象

GC刪除空閑對象的一般分為三類:

  • 清除,
  • 壓縮,
  • 復(fù)制。

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

經(jīng)歷標(biāo)記階段后,所有空閑對象占用的空間都可以重新分配新對象了。它會維護(hù)一個空閑列表,里面記錄的空閑區(qū)域的位置和大小。這種方式的缺點很明顯一是維護(hù)空閑列表增加對象開銷,二是空閑區(qū)域大小不均勻,可能會遇到分配大對象區(qū)域不夠存儲的情況。

2.4 清除壓縮(Mark-Sweep-Compact)

清除壓多了一步復(fù)制動作彌補(bǔ)標(biāo)記清除的缺點。它將所有活動對象移動到內(nèi)存區(qū)域的開頭。不過該方式的缺點是增加復(fù)制動作,也就增加了GC暫停時間。

2.5 標(biāo)記和復(fù)制

標(biāo)記復(fù)制這種方式與上面標(biāo)記清除壓縮相似,區(qū)別在于它是將活動對象復(fù)制到另外一塊新的區(qū)域(幸存對象區(qū)域)。它的好處在于復(fù)制動作可以與標(biāo)記階段同時進(jìn)行,缺點是需要另外一個存儲區(qū)域,該存儲區(qū)域應(yīng)足夠大以容納幸存的對象。

3、JVM GC

在較舊的JVM GC中(串行,并行,CMS)將堆分成三個部分:固定內(nèi)存大小的年輕代,年老代和永久代。

JVM使用兩種GC算法分別對年輕代和年老代對象進(jìn)行回收。年輕代的進(jìn)行標(biāo)記復(fù)制操作,年老代回收進(jìn)行標(biāo)記清除壓縮。

3.1 JVM GC事件

我們把GC清除堆不同區(qū)域的觸發(fā)事件分為以下幾種:

  • Minor GC 從年輕代空間回收稱為次要GC。
  • Major GC 從年老代空間回收主要GC。
  • Full GC 清理整個堆空間,包括年輕代和年老代。

3.2 Serial GC

串行GC,年輕代進(jìn)行標(biāo)記復(fù)制,年老代進(jìn)行標(biāo)記清除壓縮。兩個GC都是單線程操作,并且觸發(fā)STW,停止所有應(yīng)用線程。多CPU計算機(jī)中基本不會使用這個GC收集器。只有在單CPU的服務(wù)器上使用才有意義。

java -XX:+UseSerialGC

3.3 Parallel GC

并行GC,年輕代進(jìn)行標(biāo)記復(fù)制,年老代進(jìn)行標(biāo)記清除壓縮。不管是年輕代還是年老代GC時都會觸發(fā)STW,停止所有應(yīng)用線程。與串行GC的區(qū)別在于它是使用多個線程運(yùn)行標(biāo)記和復(fù)制/壓縮,多線程可以縮短GC收集時間。

java8默認(rèn)GC收集器就是 parallel gc。不過因為它在標(biāo)記清理階段仍然需要停止應(yīng)用線程,所以在要求較低延遲的場景下可能變得不那么適用。

可以通過-XX:ParallelGCThreads = NNN指定處理的線程數(shù)量 。默認(rèn)值等于計算機(jī)中的內(nèi)核數(shù)。

java -XX:+UseParallelGC #使用并行垃圾收集進(jìn)行清理
java -XX:+UseParallelOldGC #將并行垃圾回收用于。啟用此選項會自動設(shè)置-XX:+ UseParallelGC
java -XX:+UseParallelGC -XX:+UseParallelOldGC

3.4 Concurrent Mark and Sweep

并發(fā)標(biāo)記掃描(CMS),年輕代空間執(zhí)行并行標(biāo)記復(fù)制,年老代空間執(zhí)行并發(fā)標(biāo)記清除。年輕代GC時觸STW,停止所有應(yīng)用線程,然后多線程并行收集。年老代并發(fā)標(biāo)記清除不需要暫停應(yīng)用線程。它的意義在于著避免了Parallel GC收集器在年老代GC時的長時間停頓。

默認(rèn)情況下,此GC方式使用的線程數(shù)等于計算機(jī)物理內(nèi)核數(shù)的1/4。

java -XX:+UseConcMarkSweepGC

我們看下CMS經(jīng)歷的幾個階段

(1)初始標(biāo)記,暫停應(yīng)用線程,標(biāo)記年老代中的所有對象,這些對象是GC Roots,和年輕代中的某些活動對象引用的。

(2)并發(fā)標(biāo)記,GC與應(yīng)用程序線程并行運(yùn)行,從初始標(biāo)記中的根對象開始,遍歷年老代所有活動對象進(jìn)行標(biāo)記。

(2)并行預(yù)清除,與應(yīng)用線程同時運(yùn)行,如果某些引用發(fā)生了變更,JVM會將變化的區(qū)域標(biāo)記為臟區(qū)域。預(yù)清除階段就是對這些臟區(qū)域進(jìn)行處理,并標(biāo)記還在存活的對象,然后空閑對象將被清除。預(yù)清除可以減少重標(biāo)階段的工作量。

(4)并發(fā)可中止預(yù)清除,該階段也與應(yīng)用線程并行,屬于優(yōu)化。增加這個階段是為了讓我們能控制該階段結(jié)束的時間,也是為了減輕重標(biāo)階段的工作量。

# 控制參數(shù)
-XX:CMSScheduleRemarkEdenSizeThreshold=2M
-XX:CMSScheduleRemarkEdenPenetration=50
-XX:CMSMaxAbortablePrecleanTime=5000(單位為毫秒)


比如在并發(fā)預(yù)清理之后,如果年輕代占用高于CMSScheduleRemarkEdenSizeThreshold,則開始并發(fā)可中止的預(yù)清除并繼續(xù)進(jìn)行預(yù)清除,直到年輕代中達(dá)到CMSScheduleRemarkEdenPenetration百分比占用率,之后進(jìn)入重標(biāo)階段。如果經(jīng)過CMSMaxAbortablePrecleanTime時間仍然未達(dá)到要求,則直接進(jìn)入重標(biāo)階段。

(5)重標(biāo)階段,觸發(fā)STW,暫停所用應(yīng)用線程。從GCroots 開始掃描標(biāo)記年老代的所有活動對象。CMS會嘗試在年輕代盡可能空的時候運(yùn)行最后的備注階段。

(6)并行清理,應(yīng)用線程同時執(zhí)行。該階段的目的是刪除未使用的對象,并回收它們占用的空間以備將來使用。

(7)并行復(fù)位,并發(fā)執(zhí)行階段,重置CMS算法的內(nèi)部數(shù)據(jù)結(jié)構(gòu),并為下一個周期做好準(zhǔn)備。

:如上CMS垃圾收集器進(jìn)行大量工作為的是在年老代回收時不需要暫停應(yīng)用線程,以減少暫停時間。但是,它存在一些缺點,其中最明顯的是年老代碎片,并且在某些情況下,尤其是在大堆上,暫停持續(xù)時間缺乏可預(yù)測性。

3.5 G1 –垃圾優(yōu)先

G1是Java9默認(rèn)GC收集器。它設(shè)計的目標(biāo)是應(yīng)用在大內(nèi)存的多處理器計算機(jī),實現(xiàn)高吞吐量。一般應(yīng)用堆應(yīng)該在6GB以上且可預(yù)測的暫停時間低于0.5秒。G1作為并發(fā)標(biāo)記掃描收集器(CMS)的替代產(chǎn)品。

G1堆內(nèi)存與舊GC收集器堆內(nèi)存管理完全不同。它將堆拆分為多個較小的區(qū)域(默認(rèn)根據(jù)堆內(nèi)存拆分為接近2048份)來存對象。

G1收集器的幾個階段:

(1)初始標(biāo)記,觸發(fā)STW,標(biāo)記出從GC Roots直接訪問的所有活動對象。

(2)并發(fā)標(biāo)記,從已標(biāo)記的對象開始掃描,并從根開始標(biāo)記所有可訪問的對象。這個階段可以被年輕一代的垃圾收集打斷。

(3)重新標(biāo)記,因為并發(fā)標(biāo)記與應(yīng)用線程并行,所以可能存在遺漏的更新對象。此階段觸發(fā)STW,應(yīng)用線程暫停,完成活動對象最后的標(biāo)記。

(4)復(fù)制/清理階段,G1選擇“活度”最低的區(qū)域,這些區(qū)域可以被最快地收集。并發(fā)標(biāo)記完成后將進(jìn)行[GC pause (mixed)]混合GC,年輕代和年老代同時收集。

下圖深綠色和深藍(lán)色為清除壓縮之后的區(qū)域。

G1中幾個重要的參數(shù):

# G1區(qū)域的大小。該值為2的冪,范圍為1MB至32MB。目標(biāo)是根據(jù)最小Java堆大小具有大約2048個區(qū)域。
-XX:G1HeapRegionSize=n

# 所需的最大暫停時間設(shè)置目標(biāo)值。默認(rèn)值為200毫秒。
-XX:MaxGCPauseMillis=200

# 設(shè)置要用作年輕代大小的最小值的堆百分比。默認(rèn)值為Java堆的5%
-XX:G1NewSizePercent=5

# 設(shè)置堆大小的百分比,以用作年輕代大小的最大值。默認(rèn)值為Java堆的60%。
-XX:G1MaxNewSizePercent=60

# 設(shè)置STW工作線程的值。將n的值設(shè)置為邏輯處理器的數(shù)量。的值與n邏輯處理器的數(shù)量相同,最多為8
# 如果邏輯處理器多于八個,則將的值設(shè)置為邏輯處理器的n大約5/8。在大多數(shù)情況下,這n是可行的,但大型SPARC系統(tǒng)的值可能約為邏輯處理器的5/16。
-XX:ParallelGCThreads=n

# 設(shè)置平行標(biāo)記線的數(shù)量。設(shè)置n為并行垃圾回收線程數(shù)(ParallelGCThreads)的大約1/4 。
-XX:ConcGCThreads=n

# 設(shè)置觸發(fā)標(biāo)記周期的Java堆占用閾值。默認(rèn)占用率為整個Java堆的45%。
-XX:InitiatingHeapOccupancyPercent=45

# 設(shè)置要包含在混合垃圾收集周期中的舊區(qū)域的占用閾值。默認(rèn)占用率為65%。
-XX:G1MixedGCLiveThresholdPercent=65

# 當(dāng)可回收百分比小于堆垃圾百分比時,Java HotSpot VM不會啟動混合垃圾回收周期。默認(rèn)值為10%。
-XX:G1HeapWastePercent=10

# 設(shè)置標(biāo)記周期后混合垃圾回收的目標(biāo)數(shù)量,以收集最多包含G1MixedGCLIveThresholdPercent實時數(shù)據(jù)的舊區(qū)域。默認(rèn)值為8個混合垃圾回收?;旌橡^藏的目標(biāo)是在此目標(biāo)數(shù)量之內(nèi)。
-XX:G1MixedGCCountTarget=8

# 設(shè)置在混合垃圾收集周期中要收集的舊區(qū)域數(shù)的上限。缺省值為Java堆的10%。
-XX:G1OldCSetRegionThresholdPercent=10

# 設(shè)置保留內(nèi)存的百分比以使其保持空閑狀態(tài),以減少空間溢出的風(fēng)險。默認(rèn)值為10%。當(dāng)增加或減少百分比時,請確保將總Java堆調(diào)整相同的數(shù)量。
-XX:G1ReservePercent=10

4、總結(jié)

本文記錄GC算法基礎(chǔ)和Java中的幾種GC收集器。

到此這篇關(guān)于java中的GC收集器詳情的文章就介紹到這了,更多相關(guān)java中的GC收集器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot 中實現(xiàn)跨域的5種方式小結(jié)

    SpringBoot 中實現(xiàn)跨域的5種方式小結(jié)

    這篇文章主要介紹了SpringBoot 中實現(xiàn)跨域的5種方式小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 關(guān)于bigDecimal類的精度保留方法

    關(guān)于bigDecimal類的精度保留方法

    這篇文章主要介紹了關(guān)于bigDecimal類的精度保留方法,計算機(jī)存儲的浮點數(shù)受存儲bit位數(shù)影響,只能保證一定范圍內(nèi)精準(zhǔn),超過bit范圍的只能取近似值,Java使用java.math.BigDecimal專門處理小數(shù)精度,需要的朋友可以參考下
    2023-07-07
  • 詳解springboot shiro jwt實現(xiàn)權(quán)限管理

    詳解springboot shiro jwt實現(xiàn)權(quán)限管理

    為什么使用jwt呢,因為可以通過URL,POST參數(shù)或者在HTTP header發(fā)送,因為數(shù)據(jù)量小,傳輸速度也很快。本篇通過具體代碼來進(jìn)行詳情解析,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值
    2021-09-09
  • SpringBoot 中大文件(分片上傳)斷點續(xù)傳與極速秒傳功能的實現(xiàn)

    SpringBoot 中大文件(分片上傳)斷點續(xù)傳與極速秒傳功能的實現(xiàn)

    這篇文章主要介紹了SpringBoot 中大文件(分片上傳)斷點續(xù)傳與極速秒傳功能的實現(xiàn),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • JAVA中string數(shù)據(jù)類型轉(zhuǎn)換詳解

    JAVA中string數(shù)據(jù)類型轉(zhuǎn)換詳解

    在JAVA中string是final類,提供字符串不可以修改,string類型在項目中經(jīng)常使用,下面給大家介紹了string七種數(shù)據(jù)類型轉(zhuǎn)換,需要的朋友可以參考下
    2015-07-07
  • Spring配置文件解析之BeanDefinitionReader詳解

    Spring配置文件解析之BeanDefinitionReader詳解

    這篇文章主要介紹了Spring配置文件解析之BeanDefinitionReader詳解,ApplicationContext.xml配置文件解析成Document對象,真正對xml中元素解析的類是在BeanDefinitionDocumentReader的實現(xiàn)類中來完成的,需要的朋友可以參考下
    2024-02-02
  • java單例模式實現(xiàn)面板切換

    java單例模式實現(xiàn)面板切換

    這篇文章主要為大家詳細(xì)介紹了java單例模式實現(xiàn)面板切換,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Java IO讀取文件的實例詳解

    Java IO讀取文件的實例詳解

    這篇文章主要介紹了Java IO讀取文件的實例詳解的相關(guān)資料,主要介紹字符流和字節(jié)流的內(nèi)容,需要的朋友可以參考下
    2017-07-07
  • SpringBoot使用Jwt處理跨域認(rèn)證問題的教程詳解

    SpringBoot使用Jwt處理跨域認(rèn)證問題的教程詳解

    這篇文章主要介紹了SpringBoot使用Jwt處理跨域認(rèn)證問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • Java中ModelMapper?的高級使用

    Java中ModelMapper?的高級使用

    本文主要介紹了Java中ModelMapper?的高級使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02

最新評論

哈尔滨市| 长海县| 夹江县| 新丰县| 萍乡市| 射阳县| 高阳县| 无锡市| 穆棱市| 汝州市| 厦门市| 垫江县| 静安区| 高阳县| 海城市| 青浦区| 清原| 龙山县| 叙永县| 中超| 扬中市| 澄江县| 扎兰屯市| 仁寿县| 施甸县| 金堂县| 松原市| 同德县| 山丹县| 遵义市| 雷山县| 临沭县| 西丰县| 黄大仙区| 阿拉善左旗| 宜君县| 荣成市| 泰顺县| 定南县| 台北市| 阿巴嘎旗|