日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java的GC机制及算法

發(fā)布時(shí)間:2023/12/3 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java的GC机制及算法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載自? ?Java的GC機(jī)制及算法

GC的階段?
對(duì)每個(gè)對(duì)象而言,垃圾回收分為兩個(gè)階段:finalization和reclamation。?

  • finalization: 指運(yùn)行這個(gè)對(duì)象的finalize的方法。
  • reclamation: 回收被這個(gè)對(duì)象使用的內(nèi)存。
GC的過(guò)程的基本步驟 ?
  • 首先確認(rèn)對(duì)象是不可達(dá)的,即將被回收。
  • 其次,如果對(duì)象有finalize方法,那么對(duì)象被添加進(jìn)finalization queue中;然后在某個(gè)時(shí)間點(diǎn)finalize方法被調(diào)用以釋放finalize中的資源。
  • 最后,回收對(duì)象占用的內(nèi)存。
關(guān)于finalize方法的問(wèn)題 ?
  • finalize方法使得GC過(guò)程做了更多的事情,增加的GC的負(fù)擔(dān)。
  • 如果某個(gè)對(duì)象的finalize方法運(yùn)行時(shí)間過(guò)長(zhǎng),它會(huì)使得其他對(duì)象的finalize方法被延遲執(zhí)行。
  • finalize方法中如果創(chuàng)建了strong reference引用了其他對(duì)象,這會(huì)阻止此對(duì)象被GC。
  • finalize方法有可能以不可確定的順序執(zhí)行(也就是說(shuō)要在安全性要求嚴(yán)格的場(chǎng)景中盡量避免使用finalize方法)。
  • 不確保finalize方法會(huì)被及時(shí)調(diào)用,也許程序都退出了,但是finalize方法還沒被調(diào)用。
對(duì)象引用的類型 ?
  • Reference(or named Strong Reference)(?強(qiáng)引用):普通類型的引用。
  • SoftReference(?軟引用):被這種引用指向的對(duì)象,如果此對(duì)象沒要再被其他Strong Reference引用的話,可能在任何時(shí)候被GC。雖然是可能在任何時(shí)候被GC,但是通常是在可用內(nèi)存數(shù)比較低的時(shí)候,并且在程序拋出OutOfMemoryError之前才發(fā)生對(duì)此對(duì)象的GC。SoftReference通常被用作實(shí)現(xiàn)Cache的對(duì)象引用,如果這個(gè)對(duì)象被GC了,那么他可以在任何時(shí)候再重新被創(chuàng)建。另外,根據(jù)JDK文檔中介紹,實(shí)際JVM的實(shí)現(xiàn)是鼓勵(lì)不回收最近創(chuàng)建和最近使用的對(duì)象。SoftReference?類的一個(gè)典型用途就是用于內(nèi)存敏感的高速緩存。
  • WeakReference(弱引用):如果一個(gè)被WeakReference引用的對(duì)象,當(dāng)沒要任何SoftReference和StrongReference引用時(shí),立即會(huì)被GC。和SoftReference的區(qū)別是:WeakReference對(duì)象是被eagerly collected,即一旦沒要任何SoftReference和StrongReference引用,立即被清楚;而只被SoftReference引用的對(duì)象,不回立即被清楚,只有當(dāng)內(nèi)存不夠,即將發(fā)生OutOfMemoryError時(shí)才被清除,而且是先清除不常用的。SoftReference適合實(shí)現(xiàn)Cache用。WeakReference 類的一個(gè)典型用途就是規(guī)范化映射( canonicalized mapping )
  • PhantomReference(虛引用):當(dāng)沒有StrongReference,SoftReference和WeakReference引用時(shí),隨時(shí)可被GC。通常和ReferenceQueue聯(lián)合使用,管理和清除與被引用對(duì)象(沒有finalize方法)相關(guān)的本地資源。
衡量GC的指標(biāo)(GC Metrics) ?
  • Throughput(吞吐量):所有沒有花在執(zhí)行GC上的時(shí)間占總運(yùn)行時(shí)間的比重。
  • Pauses(暫停):當(dāng)GC在運(yùn)行時(shí)程序的暫停次數(shù)。或者是在感興趣的暫停次數(shù)中,暫停的平均時(shí)長(zhǎng)和最大時(shí)長(zhǎng)。
  • Footprint(足跡?):當(dāng)前使用的堆內(nèi)存大小。
  • Promptness(及時(shí)性):不再使用的對(duì)象多久能被清除掉并釋放其內(nèi)存。
通用GC算法 ?
Java所使用的所有的GC算法都是通用GC算法概念的變種。?
通用GC算法的假設(shè):?
  • 最近創(chuàng)建的對(duì)象很可能很快就不可達(dá)了(unreachable,即可被回收了),比如方法內(nèi)部聲明的本地變量,當(dāng)程序運(yùn)行出了本地變量的作用范圍后,本地變量引用的對(duì)象就很快不可達(dá)了。
  • 一個(gè)對(duì)象保持可達(dá)(reachable)的越久就越不可能被回收。
在Java GC中,對(duì)象被劃分為generations(代)或spaces(空間)。Java把對(duì)象分為young(年輕代),tenured(年老代)和perm(永久代)。在GC過(guò)程中,對(duì)象從一個(gè)space(空間)移動(dòng)到另一個(gè)space。?
Object Spaces(對(duì)象空間) ?
  • Young:年輕代中保存著剛創(chuàng)建的對(duì)象,這個(gè)代中的對(duì)象能夠“minor” or “major” 收集中被回收。
  • Tenured:年老代中保存著從年輕代中幸存下來(lái)的對(duì)象,只能夠在“major”中被回收。
  • Perm:永久代中保存著JVM所需的對(duì)象,比如Class對(duì)象和Method對(duì)象,以及他們的字節(jié)碼和內(nèi)部字符串等。對(duì)Perm中的對(duì)象GC意味著所有的Class都被卸載了。
每塊空間的大小由當(dāng)前的對(duì)內(nèi)存大小決定,并且能夠在運(yùn)行時(shí)改變。每個(gè)空間之間的關(guān)系如下圖所示:?
?

Young Spaces(年輕空間) ?
  • Eden space:存儲(chǔ)自從上次GC完畢之后新創(chuàng)建的對(duì)象,除了屬于Perm的對(duì)象。當(dāng)minor collection發(fā)生時(shí),Eden space中的對(duì)象或者GC清理掉,或者被移到survivor space。
  • Survivor spaces:這個(gè)空間中存儲(chǔ)的是自從上次GC幸存下來(lái)的young object。在minor GC中,這些對(duì)象或者被GC清理掉,或者被移到另外一個(gè)survivor空間中。
Minor collections和Major collections ?
  • Minor collection當(dāng)young space被占滿時(shí)執(zhí)行。它比major collections快,因?yàn)閙inor collection僅僅檢查major collection相應(yīng)的一個(gè)子集對(duì)象。minor collection比major collection發(fā)生的頻率高。
  • Major collection當(dāng)tenured space被占滿時(shí)執(zhí)行。他會(huì)清理tenured和young。
GC運(yùn)行的三種方式 ?
在java5和java6中有4中垃圾回收的算法,有一種算法將不再支持,剩余的三種垃圾回收算法是: serial , throughput ?and? concurrent low pause 。?
  • Stop the world(停止所有程序的方式):在這種方式運(yùn)行的GC,在GC完成前,JVM中的所有程序都不允許運(yùn)行。Serial collector此時(shí)做minor和major收集。Throughput collector此時(shí)做major collector。
  • Incremental(增量運(yùn)行方式):目前沒要Java GC算法支持這種運(yùn)行方式。GC以這種方式運(yùn)行時(shí),GC允許程序做一小段時(shí)間的工作,然后做垃圾回收工作。
  • Concurrent(并行運(yùn)行):Throughput collector此時(shí)做minor collect,Concurrent low pause collector此時(shí)做minor和major收集。在這種運(yùn)行方式下,GC和程序并行的運(yùn)行,因此程序僅僅被短暫的暫停。
GC算法 ?
  • Serial算法: 使用-XX:+UseSerialGC開啟此算法的GC。GC使用和應(yīng)用程序相同的線程去做minor collection和major collection。
  • Throughput:使用-XX:+UseParallelGC開啟此算法GC。GC使用多線程去做minor collection以減少程序停止的時(shí)間。但是對(duì)于major collection,還是使用同程序相同的線程去做。當(dāng)具有多核cpu時(shí),并且程序有大量的短生命周期的對(duì)象時(shí),并且對(duì)程序停頓時(shí)間不限制時(shí)較好。
  • Concurrent Low Pause: 使用-XX:+UseConcMarkSweepGC開啟此算法GC。使用多線程去做minor和major collection。當(dāng)具有多核cpu,并且程序有大量的長(zhǎng)生命周期的對(duì)象,并且對(duì)程序停頓時(shí)間有限制時(shí),效果較好。
什么時(shí)候發(fā)生GC ?
GC發(fā)生的時(shí)刻受堆內(nèi)存大小的影響。如果堆內(nèi)存小,GC會(huì)執(zhí)行的很快,但是又會(huì)很快的被填滿,因此GC比頻繁;如果堆內(nèi)存很大,GC會(huì)執(zhí)行的較慢,而且不會(huì)很快被填滿,因此執(zhí)行的比較頻率比較低。?

基本的GC調(diào)試 ?
throughput goal -XX:GCTimeRatio=n: 表示花費(fèi)總時(shí)間百分之多少的CPU時(shí)間去運(yùn)行程序。?
maximum pause time goal -XX:MaxGCPauseMillis=n:每次GC時(shí)程序暫停最多多少毫秒。?
footprint goal:如果其他目標(biāo)都達(dá)到了,那么首先減少heap size,直到前兩個(gè)goal不再滿足,然后再慢慢增加。直到滿足前面兩個(gè)goal。?
-Xms=n (starting) and -Xmx=n (maximum) heap size,這兩個(gè)參數(shù)應(yīng)該都很熟悉,就是JVM使用的最小堆內(nèi)存數(shù)和最大堆內(nèi)存數(shù)。?
-XX:MinHeapFreeRatio=n, -XX:MaxHeapFreeRatio=n:最小和最大的空閑堆內(nèi)存和被使用堆內(nèi)存的比例。當(dāng)空閑堆內(nèi)存比例小于MinHeapFreeRatio時(shí),內(nèi)存空間開始擴(kuò)展。當(dāng)空閑堆內(nèi)存比例大于MaxHeapFreeRatio時(shí),內(nèi)存空間開始減小。?
-XX:NewSize=n, -XX:MaxNewSize=n:默認(rèn)的young space的大小(包括eden + survivor 1 + survivor 2)。?
-XX:NewRatio=n:young和tenured的比例。?
-XX:SurvivorRatio=n:每個(gè)survivor space 和 eden之間的比例。?
-XX:MaxPermSize=n:perm的最大size。?
-XX:TargetSurvivorRatio=n:每次GC之后幸存下來(lái)的空間的目標(biāo)比例。?
-XX:+DisableExplicitGC:當(dāng)此參數(shù)打開時(shí),在程序中調(diào)用System.gc()將會(huì)不起作用。默認(rèn)是off。?
-XX:+ScavengeBeforeFullGC:當(dāng)打開此參數(shù)時(shí),在每次major collection時(shí)先執(zhí)行一次minor collection。默認(rèn)打開。?
-XX:+UseGCOverheadLimit:當(dāng)打開此參數(shù)時(shí),如果總運(yùn)行時(shí)間的98%的時(shí)間都在做GC,則拋出OutOfMemmoryError。默認(rèn)打開。?

參考資料: http://java.ociweb.com/mark/other-presentations/JavaGC.pdf ?

總結(jié)

以上是生活随笔為你收集整理的Java的GC机制及算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。