日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Java的垃圾回收機制詳解和調(diào)優(yōu)大 - 日志 - 肖波 - Talentdigger - ...

 風自向前 2010-08-03
首先,這篇純屬個人收集的資料,不是我寫的。在寫作業(yè)時沒用上,在這發(fā)一下。
gc即垃圾收集機制是指JVM用于釋放那些不再使用的對象所占用的內(nèi)存。Java語言并不要求JVM有gc,也沒有規(guī)定gc如何工作。不過常用的JVM都有gc,而且大多數(shù)gc都使用類似的算法管理內(nèi)存和執(zhí)行收集操作。 
在充分理解了垃圾收集算法和執(zhí)行過程后,才能有效的優(yōu)化它的性能。有些垃圾收集專用于特殊的應用程序。比如,實時應用程序主要是為了避免垃圾收集中斷,而大多數(shù)OLTP應用程序則注重整體效率。理解了應用程序的工作負荷和JVM支持的垃圾收集算法,便可以進行優(yōu)化配置垃圾收集器。 
垃圾收集的目的在于清除不再使用的對象。gc通過確定對象是否被活動對象引用來確定是否收集該對象。gc首先要判斷該對象是否是時候可以收集。兩種常用的方法是引用計數(shù)和對象引用遍歷。 
1.1.引用計數(shù) 
引用計數(shù)存儲對特定對象的所有引用數(shù),也就是說,當應用程序創(chuàng)建引用以及引用超出范圍時,JVM必須適當增減引用數(shù)。當某對象的引用數(shù)為0時,便可以進行垃圾收集。 
1.2.對象引用遍歷 
早期的JVM使用引用計數(shù),現(xiàn)在大多數(shù)JVM采用對象引用遍歷。對象引用遍歷從一組對象開始,沿著整個對象圖上的每條鏈接,遞歸確定可到達(reachable)的對象。如果某對象不能從這些根對象的一個(至少一個)到達,則將它作為垃圾收集。在對象遍歷階段,gc必須記住哪些對象可以到達,以便刪除不可到達的對象,這稱為標記(marking)對象。 
下一步,gc要刪除不可到達的對象。刪除時,有些gc只是簡單的掃描堆棧,刪除未標記的未標記的對象,并釋放它們的內(nèi)存以生成新的對象,這叫做清除(sweeping)。這種方法的問題在于內(nèi)存會分成好多小段,而它們不足以用于新的對象,但是組合起來卻很大。因此,許多gc可以重新組織內(nèi)存中的對象,并進行壓縮(compact),形成可利用的空間。 
為此,gc需要停止其他的活動活動。這種方法意味著所有與應用程序相關的工作停止,只有gc運行。結果,在響應期間增減了許多混雜請求。另外,更復雜的gc不斷增加或同時運行以減少或者清除應用程序的中斷。有的gc使用單線程完成這項工作,有的則采用多線程以增加效率。 
2.幾種垃圾回收機制 
2.1.標記-清除收集器 
這種收集器首先遍歷對象圖并標記可到達的對象,然后掃描堆棧以尋找未標記對象并釋放它們的內(nèi)存。這種收集器一般使用單線程工作并停止其他操作。 
2.2.標記-壓縮收集器 
有時也叫標記-清除-壓縮收集器,與標記-清除收集器有相同的標記階段。在第二階段,則把標記對象復制到堆棧的新域中以便壓縮堆棧。這種收集器也停止其他操作。 
2.3.復制收集器 
這種收集器將堆棧分為兩個域,常稱為半空間。每次僅使用一半的空間,JVM生成的新對象則放在另一半空間中。gc運行時,它把可到達對象復制到另一半空間,從而壓縮了堆棧。這種方法適用于短生存期的對象,持續(xù)復制長生存期的對象則導致效率降低。 
2.4.增量收集器 
增量收集器把堆棧分為多個域,每次僅從一個域收集垃圾。這會造成較小的應用程序中斷。 
2.5.分代收集器 
這種收集器把堆棧分為兩個或多個域,用以存放不同壽命的對象。JVM生成的新對象一般放在其中的某個域中。過一段時間,繼續(xù)存在的對象將獲得使用期并轉入更長壽命的域中。分代收集器對不同的域使用不同的算法以優(yōu)化性能。 
2.6.并發(fā)收集器 
并發(fā)收集器與應用程序同時運行。這些收集器在某點上(比如壓縮時)一般都不得不停止其他操作以完成特定的任務,但是因為其他應用程序可進行其他的后臺操作,所以中斷其他處理的實際時間大大降低。 
2.7.并行收集器 
并行收集器使用某種傳統(tǒng)的算法并使用多線程并行的執(zhí)行它們的工作。在多cpu機器上使用多線程技術可以顯著的提高Java應用程序的可擴展性。
 
 
 
2 Java的垃圾回收機制詳解和調(diào)優(yōu)大全 
 
3.Sun HotSpot 
1.4.1 JVM堆大小的調(diào)整 
Sun HotSpot 1.4.1使用分代收集器,它把堆分為三個主要的域:新域、舊域以及永久域。JVM生成的所有新對象放在新域中。一旦對象經(jīng)歷了一定數(shù)量的垃圾收集循環(huán)后,便獲得使用期并進入舊域。 
在永久域中JVM則存儲class和method對象。就配置而言,永久域是一個獨立域并且不認為是堆的一部分。下面介紹如何控制這些域的大小??墒褂?Xms和-Xmx 控制整個堆的原始大小或最大值。 
下面的命令是把初始大小設置為128M: 

Java –Xms128m
 

–Xmx256m為控制新域的大小,可使用-XX:NewRatio設置新域在堆中所占的比例。下面的命令把整個堆設置成128m,新域比率設置成3,即新域與舊域比例為1:3,新域為堆的1/4或32M: 

Java –Xms128m –Xmx128m
 

–XX:NewRatio =3可使用-XX:NewSize和-XX:MaxNewsize設置新域的初始值和最大值。 
下面的命令把新域的初始值和最大值設置成64m: 

Java –Xms256m –Xmx256m –Xmn64m
 

永久域默認大小為4m。運行程序時,JVM會調(diào)整永久域的大小以滿足需要。每次調(diào)整時,JVM會對堆進行一次完全的垃圾收集。 
使用-XX:MaxPerSize標志來增加永久域搭大小。在WebLogic Server應用程序加載較多類時,經(jīng)常需要增加永久域的最大值。當JVM加載類時,永久域中的對象急劇增加,從而使JVM不斷調(diào)整永久域大小。為了避免調(diào)整,可使用-XX:PerSize標志設置初始值。下面把永久域初始值設置成32m,最大值設置成64m。 

Java -Xms512m -Xmx512m -Xmn128m 
-XX:PermSize=32m
-XX:MaxPermSize=64m
 

默認狀態(tài)下,HotSpot在新域中使用復制收集器。該域一般分為三個部分。第一部分為Eden,用于生成新的對象。另兩部分稱為救助空間,當Eden充滿時,收集器停止應用程序,把所有可到達對象復制到當前的from救助空間,一旦當前的from救助空間充滿,收集器則把可到達對象復制到當前的to救助空間。 
From和to救助空間互換角色。維持活動的對象將在救助空間不斷復制,直到它們獲得使用期并轉入舊域。使用-XX:SurvivorRatio可控制新域子空間的大小。 
同NewRation一樣,SurvivorRation規(guī)定某救助域與Eden空間的比值。比如,以下命令把新域設置成64m,Eden占32m,每個救助域各占16m: 

Java -Xms256m -Xmx256m -Xmn64m 
-XX:SurvivorRation =2
 

如前所述,默認狀態(tài)下HotSpot對新域使用復制收集器,對舊域使用標記-清除-壓縮收集器。在新域中使用復制收集器有很多意義,因為應用程序生成的大部分對象是短壽命的。理想狀態(tài)下,所有過渡對象在移出Eden空間時將被收集。 
如果能夠這樣的話,并且移出Eden空間的對象是長壽命的,那么理論上可以立即把它們移進舊域,避免在救助空間反復復制。但是,應用程序不能適合這種理想狀態(tài),因為它們有一小部分中長壽命的對象。 
最好是保持這些中長壽命的對象并放在新域中,因為復制小部分的對象總比壓縮舊域廉價。為控制新域中對象的復制,可用-XX:TargetSurvivorRatio控制救助空間的比例(該值是設置救助空間的使用比例。 
如救助空間位1M,該值50表示可用500K)。該值是一個百分比,默認值是50。當較大的堆棧使用較低的sruvivorratio時,應增加該值到80至90,以更好利用救助空間。用-XX:maxtenuring threshold可控制上限。 
為放置所有的復制全部發(fā)生以及希望對象從eden擴展到舊域,可以把MaxTenuring Threshold設置成0。設置完成后,實際上就不再使用救助空間了,因此應把SurvivorRatio設成最大值以最大化Eden空間,設置如下: 

Java … -XX:MaxTenuringThreshold=0
–XX:SurvivorRatio=50000 …
4.BEA JRockit JVM的使用 
Bea WebLogic 8.1使用的新的JVM用于Intel平臺。在Bea安裝完畢的目錄下可以看到有一個類似于jrockit81sp1_141_03的文件夾。這就是Bea新JVM所在目錄。不同于HotSpot把Java字節(jié)碼編譯成本地碼,它預先編譯成類。 
 
 
 
3 Java的垃圾回收機制詳解和調(diào)優(yōu)大全 
 
JRockit還提供了更細致的功能用以觀察JVM的運行狀態(tài),主要是獨立的GUI控制臺(只能適用于使用Jrockit才能使用jrockit81sp1_141_03自帶的console監(jiān)控一些cpu及memory參數(shù))或者WebLogic Server控制臺。 
Bea JRockit JVM支持4種垃圾收集器: 
4.1.1.分代復制收集器 
它與默認的分代收集器工作策略類似。對象在新域中分配,即JRockit文檔中的nursery。這種收集器最適合單cpu機上小型堆操作。 
4.1.2.單空間并發(fā)收集器 
該收集器使用完整堆,并與背景線程共同工作。盡管這種收集器可以消除中斷,但是收集器需花費較長的時間尋找死對象,而且處理應用程序時收集器經(jīng)常運行。如果處理器不能應付應用程序產(chǎn)生的垃圾,它會中斷應用程序并關閉收集。 
分代并發(fā)收集器 這種收集器在護理域使用排它復制收集器,在舊域中則使用并發(fā)收集器。由于它比單空間共同發(fā)生收集器中斷頻繁,因此它需要較少的內(nèi)存,應用程序的運行效率也較高,注意,過小的護理域可以導致大量的臨時對象被擴展到舊域中。這會造成收集器超負荷運作,甚至采用排它性工作方式完成收集。 
4.1.3.并行收集器 
該收集器也停止其他進程的工作,但使用多線程以加速收集進程。盡管它比其他的收集器易于引起長時間的中斷,但一般能更好的利用內(nèi)存,程序效率也較高。 
默認狀態(tài)下,JRockit使用分代并發(fā)收集器。要改變收集器,可使用: 

-Xgc:
 

對應四個收集器分別為gencopy,singlecon,gencon以及parallel。可使用-Xms和-Xmx設置堆的初始大小和最大值。要設置護理域,則使用: 

-Xns:Java –jrockit –Xms512m 
–Xmx512m –Xgc:gencon –Xns128m…
 

盡管JRockit支持-verbose:gc開關,但它輸出的信息會因收集器的不同而異。JRockit還支持memory、load和codegen的輸出。 
注意 :如果 使用JRockit JVM的話還可以使用WLS自帶的console(C:\bea\jrockit81sp1_141_03\bin下)來監(jiān)控一些數(shù)據(jù),如cpu,memery等。要想能構監(jiān)控必須在啟動服務時startWeblogic.cmd中加入-Xmanagement參數(shù)。 
5.如何從JVM中獲取信息來進行調(diào)整 
-verbose.gc開關可顯示gc的操作內(nèi)容。打開它,可以顯示最忙和最空閑收集行為發(fā)生的時間、收集前后的內(nèi)存大小、收集需要的時間等。打開-xx:+ printgcdetails開關,可以詳細了解gc中的變化。 
打開-XX: + PrintGCTimeStamps開關,可以了解這些垃圾收集發(fā)生的時間,自JVM啟動以后以秒計量。最后,通過-xx: + PrintHeapAtGC開關了解堆的更詳細的信息。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多