Garbage collection (GC) 是 Java Virtual Machine (JVM) 的必要組成部分,它收集沒有使用的 Java 堆內(nèi)存,以便應(yīng)用程序可以繼續(xù)分配新的對(duì)象。GC 的效果和性能對(duì)于應(yīng)用程序性能和確定 (determinism) 非常重要。IBM WebSphere Application Server V8 附帶的 IBM JVM(在受支持的平臺(tái)上)提供 4 種 GC 策略算法:
-Xgcpolicy:optthruput
-Xgcpolicy:optavgpause
-Xgcpolicy:gencon
-Xgcpolicy:balanced
每種算法都提供不同的性能和決定質(zhì)量。此外,WebSphere Application Server
V8 中的默認(rèn)策略已從 -Xgcpolicy:optthruput
更改為 -Xgcpolicy:gencon
策略。下面我們逐一檢查這些策略,看看這個(gè)默認(rèn)策略更改對(duì)它們有何影響。
不同應(yīng)用程序自然有不同的內(nèi)存使用模式。計(jì)算密集型數(shù)字處理工作負(fù)載使用 Java 堆 (heap) 的方式不同于面向客戶的高度事務(wù)型接口。要以最佳方式處理這些不同種類的工作負(fù)載,則需要使用不同的垃圾收集策略。IBM JVM 支持許多垃圾收集策略,它允許您選擇最適合您的應(yīng)用程序的策略。
平行式 “標(biāo)記-清掃-壓縮” 收集器:optthruput
最簡(jiǎn)單的垃圾收集技術(shù)可能是:持續(xù)分配直到耗盡閑置內(nèi)存,然后停止應(yīng)用程序,處理整個(gè)堆。盡管這種技術(shù)可能會(huì)生成一個(gè)非常有效的垃圾收集器,但這意味著用戶程序必須能容忍收集器帶來的暫停。只關(guān)注總流量的工作負(fù)載可能會(huì)從這種策略中受益。
optthruput 策略 (-Xgcpolicy:optthruput
) 采用的就是這種策略(參見圖 1)。這個(gè)收集器)使用一種平行的 “標(biāo)記-清掃 (mark-sweep)” 算法。簡(jiǎn)言之,這意味著收集器首先逐一訪問可訪問的對(duì)象,將它們標(biāo)記為實(shí)時(shí)數(shù)據(jù)。然后,第二輪訪問掃除未標(biāo)記的對(duì)象,將未使用的閑置內(nèi)存留作新分配之用。大部分這種工作都可以并行完成,因此收集器可以使用額外的線程(默認(rèn)情況下使用的最大線程數(shù)為 CPU 的數(shù)量)來加快工作速度,減少應(yīng)用程序的暫停時(shí)間。
圖 1. 應(yīng)用程序和收集器 CPU 使用情況:optthruput

“標(biāo)記-清掃” 算法的問題是可能會(huì)導(dǎo)致碎片(fragmentation),如圖 2 所示。盡管可能有大量閑置內(nèi)存,但如果它們只是一些小塊,其間夾雜著活動(dòng)對(duì)象,那么可能沒有哪個(gè)碎塊大到足以滿足某個(gè)特定分配需求。
這個(gè)問題的解決方法是壓縮(compaction)。理論上,壓縮程序會(huì)將所有活動(dòng)對(duì)象都移動(dòng)到堆的一端,留下一塊連續(xù)的閑置空間。這是一項(xiàng)昂貴的操作,因?yàn)榭赡軙?huì)移動(dòng)每個(gè)活動(dòng)對(duì)象,每個(gè)經(jīng)過移動(dòng)的對(duì)象的指針都必須更新為新位置。因此,通常只在萬不得已時(shí)才進(jìn)行壓縮。壓縮也可以并行執(zhí)行,但這會(huì)降低活動(dòng)對(duì)象的打包效果,可能會(huì)生成幾個(gè)較小的閑置空間,而不是一整塊閑置空間。
圖 2. 堆碎片

對(duì)于愿意損失部分流量、減少暫停時(shí)間的應(yīng)用程序而言,可以選擇另一種策略。optavgpause 策略(-Xgcpolicy:optavgpause
)試圖在停止應(yīng)用程序之前盡可能多完成一些 GC 工作,從而縮短暫停時(shí)間(參見圖 3)。這種策略也使用 “標(biāo)記-清掃-壓縮 (mark-sweep-compact)” 收集器,但大部分標(biāo)記和清掃工作可以在應(yīng)用程序運(yùn)行時(shí)執(zhí)行。根據(jù)程序的分配速度,系統(tǒng)試圖預(yù)測(cè)下次需要執(zhí)行垃圾收集的時(shí)間。達(dá)到這個(gè)閾值時(shí),就會(huì)啟動(dòng)一個(gè)并發(fā) GC。當(dāng)應(yīng)用程序線程分配對(duì)象時(shí),系統(tǒng)偶爾會(huì)要求它們?cè)谕瓿煞峙涔ぷ髦皥?zhí)行少量 GC 工作。線程執(zhí)行的分配工作越多,要求它完成的 GC 工作也越多。與此同時(shí),會(huì)有一個(gè)或多個(gè)背景 GC 線程使用閑置周期完成余下的工作。如果已經(jīng)完成所有并發(fā)工作,或者閑置內(nèi)存提前耗盡,則將中止應(yīng)用程序并完成收集工作。這種暫停通常比較短,除非需要進(jìn)行壓縮。由于壓縮需要移動(dòng)和更新活動(dòng)對(duì)象,因此不能并發(fā)執(zhí)行。
圖 3. 應(yīng)用程序和收集器 CPU 使用情況:optavgpause

很久以前,人們就注意到,創(chuàng)建的大多數(shù)對(duì)象只被使用一小段時(shí)間。這是編程技術(shù)和應(yīng)用程序類型所導(dǎo)致的結(jié)果。許多常用 Java 慣用語都會(huì)創(chuàng)建一些將迅速棄用的幫助程序 (helper) 對(duì)象,比如 StringBuffer/StringBuilder
對(duì)象和 Iterator 對(duì)象。可以分配這些對(duì)象來完成某個(gè)特定任務(wù),任務(wù)完成后就很少會(huì)再用到這些對(duì)象。在更大的范圍內(nèi),實(shí)際上事務(wù)型應(yīng)用程序也常常創(chuàng)建一些 “一次性使用、用完作廢” 的對(duì)象組。一旦返回?cái)?shù)據(jù)庫查詢的響應(yīng)之后,就不再需要回復(fù)、中間狀態(tài)和查詢本身。
這種發(fā)現(xiàn)導(dǎo)致了分代(generational)垃圾收集器的開發(fā)。其背后的理念是:將堆分割為多個(gè)不同區(qū)域,以不同的速度收集這些區(qū)域。新對(duì)象被分配到一個(gè)稱為托兒所(nursery)(或新空間)的區(qū)域中。由于這個(gè)區(qū)域中的大多數(shù)對(duì)象很快都將變?yōu)槔允占搮^(qū)域最有利于恢復(fù)內(nèi)存。如果某個(gè)對(duì)象可能會(huì)存活一段時(shí)間,則會(huì)將它移動(dòng)到另一個(gè)稱為保留區(qū) (tenure)(或舊空間)的區(qū)域中。這些對(duì)象不太可能變?yōu)槔?,因此收集器很少檢查它們。對(duì)于適當(dāng)?shù)墓ぷ髫?fù)載,進(jìn)行垃圾收集的結(jié)果是:由于檢查的內(nèi)存更少,收集更快更有效;而且,經(jīng)過檢查的對(duì)象被回收的比例更高一些。收集更快意味著暫停時(shí)間更短,因此應(yīng)用程序響應(yīng)性也更好。
IBM 的 gencon 策略(-Xgcpolicy:gencon
)在上述并發(fā)策略之上提供了一個(gè)分代 GC( “gen-”)。保留區(qū)空間如上所述收集,而
托兒所空間使用了一個(gè)復(fù)制 (copying) 收集器。這種算法的工作方式是將托兒所區(qū)域進(jìn)一步細(xì)分為分配 (allocate) 和幸存者 (survivor) 空間(參見圖 4)。新對(duì)象被放置到分配空間中,直到耗盡其閑置空間。然后,應(yīng)用程序會(huì)停止,分配空間中的所有活動(dòng)對(duì)象都將復(fù)制到幸存者空間中。然后這兩個(gè)空間交換角色:分配空間變?yōu)樾掖嬲呖臻g,幸存者空間變?yōu)榉峙淇臻g,應(yīng)用程序恢復(fù)運(yùn)行。如果某個(gè)對(duì)象在幾輪復(fù)制之后得以幸存,則會(huì)將它移動(dòng)到保留區(qū)空間中。
圖 4. gencon 應(yīng)用

理論上,這意味著托兒所空間的一半(即幸存者空間)在任何時(shí)點(diǎn)上都未使用。實(shí)際上,預(yù)留為幸存者空間的內(nèi)存量會(huì)根據(jù)在每次收集中幸存下來的對(duì)象的百分比進(jìn)行實(shí)時(shí)調(diào)整。如果大多數(shù)新對(duì)象都被收集(這是預(yù)期的情況),那么分配空間和幸存者空間之間的分界線就會(huì)傾斜,此時(shí)需要增加垃圾收集之前可以分配的數(shù)據(jù)量。
這種風(fēng)格的收集器有一個(gè)重大好處:通過在每次收集時(shí)移動(dòng)活動(dòng)對(duì)象,托兒所區(qū)域在每次收集時(shí)都被隱式壓縮。這會(huì)導(dǎo)致閑置空間塊變得盡可能的大,但也可能會(huì)將關(guān)系密切的對(duì)象(例如 String
及其 char[]
數(shù)據(jù))移動(dòng)到臨近的內(nèi)存位置。這有助于改進(jìn)系統(tǒng)內(nèi)存緩存的性能特征,從而提高應(yīng)用程序本身的性能。
托兒所垃圾收集的成本與幸存的數(shù)據(jù)量有關(guān)(參見圖 5)。由于預(yù)期的情況是多數(shù)對(duì)象都將是垃圾,因此一次托兒所收集通常導(dǎo)致很短的暫停。盡管應(yīng)該能夠快速收集多數(shù)對(duì)象,但有些對(duì)象無法收集。這意味著隨著時(shí)間的推移,保留區(qū)區(qū)域中將塞滿了長(zhǎng)期存活的對(duì)象,最終導(dǎo)致需要對(duì)整個(gè)堆進(jìn)行一次垃圾收集。上述并發(fā)收集器使用的大部分技術(shù)在這里仍然適用。保留區(qū)區(qū)域的標(biāo)記將根據(jù)需要并發(fā)運(yùn)行,而分配和收集是在托兒所區(qū)域中進(jìn)行的。在 gencon 策略下,保留區(qū)區(qū)域的清掃不是并發(fā)執(zhí)行的,而是作為保留區(qū)主收集的一部分進(jìn)行的。
圖 5. 應(yīng)用程序和收集器 CPU 使用情況:gencon

WebSphere Application
Server V8 中添加了一個(gè)新的垃圾收集策略。這個(gè)策略名為 balanced(-Xgcpolicy:balanced
),它擴(kuò)展了擁有多個(gè)不同的堆區(qū)域這個(gè)概念,將堆劃分為大量區(qū)域,每個(gè)區(qū)域都可以單獨(dú)處理。本系列第 2 部分將詳細(xì)介紹基于區(qū)域的垃圾收集的基礎(chǔ)知識(shí),特別是將深入討論 balanced 策略。
要調(diào)優(yōu)任何應(yīng)用程序的堆大小,第一步是使用默認(rèn)堆設(shè)置運(yùn)行應(yīng)用程序,這允許您測(cè)量開箱即用性能。此時(shí),如果堆閑置空間總是低于 40%,或者 GC 暫停高于總運(yùn)行時(shí)間的 10%,就應(yīng)該考慮增加堆大小。最小堆大小和最大堆大小可以分別通過 -Xms<value>
和 -Xmx<value>
修改。
用于垃圾收集的標(biāo)記和清掃階段的 GC 暫停時(shí)間基于堆上的活動(dòng)對(duì)象的數(shù)量。當(dāng)您增加統(tǒng)一工作負(fù)載上的堆大小時(shí),標(biāo)記和清掃階段將繼續(xù)花費(fèi)大致相同的時(shí)間完成操作。因此,通過增加堆大小,可以增加 GC 暫停之間的間隔,從而為應(yīng)用程序提供更多的執(zhí)行時(shí)間。
如果 GC 由于碎片問題而執(zhí)行壓縮,那么增加堆大小可能有助于緩解壓縮導(dǎo)致的長(zhǎng)時(shí)暫停問題。壓縮階段可能會(huì)極大地增加 GC 暫停時(shí)間,因此,如果壓縮階段經(jīng)常出現(xiàn),那么調(diào)優(yōu)堆設(shè)置就能改進(jìn)應(yīng)用程序性能。
使用可變大小堆允許 GC 僅對(duì)堆使用應(yīng)用程序必需的 OS 資源。隨著應(yīng)用程序程序堆需求的變化,GC 可以通過擴(kuò)大和收縮堆做出反應(yīng)。GC 只能收縮從堆末尾開始的連續(xù)內(nèi)存塊,因此收縮堆可能需要進(jìn)行壓縮。實(shí)際的收縮和擴(kuò)大階段很快就能完成,不會(huì)明顯增加 GC 暫停時(shí)間。通過將最大堆大小設(shè)置為略大于常規(guī)操作所需的大小,應(yīng)用程序能夠通過擴(kuò)大堆來處理額外的工作負(fù)載。
堆需求不變的應(yīng)用程序可以通過使用固定堆大小改進(jìn) GC 暫停時(shí)間。
調(diào)優(yōu)分代垃圾收集時(shí),最簡(jiǎn)單的方法是將托兒所空間視為非分代垃圾收集使用的 Java 堆區(qū)域之外的新 Java 堆區(qū)域。這樣,非分代垃圾收集使用的 Java 堆就變成了保留區(qū)堆。
這種方法是一種保守方法:預(yù)期的情況是保留區(qū)堆的占用率將由于托兒所空間的引入而降低,但它提供了一個(gè)安全的起點(diǎn),特別是從非分代策略遷移時(shí)。當(dāng)可以監(jiān)控全局(完全)收集之后的保留區(qū)堆的占用率時(shí),就可以按照 前面 描述的方法來調(diào)整堆大?。?/p>
-Xmn<size>
設(shè)置托兒所區(qū)域的初始和最大大小,有效地設(shè)置-Xmns
和-Xmnx
。-Xmns<size>
將托兒所區(qū)域的初始大小設(shè)置為指定的值。-Xmnx<size>
將托兒所區(qū)域的最大大小設(shè)置為指定的值。
托兒所堆大小應(yīng)該是固定的,因此只需要這些選項(xiàng)中的一個(gè):-Xmn
。因此,您只需理解如何正確設(shè)置托兒所堆大小。
要正確設(shè)置托兒所堆大小,首先需要考慮托兒所收集使用的機(jī)制,然后考慮隨之出現(xiàn)的二級(jí)特征:
- 托兒所收集的工作方式是將數(shù)據(jù)從分配空間復(fù)制到幸存者空間。復(fù)制數(shù)據(jù)是一個(gè)比較昂貴耗時(shí)的任務(wù)。因此,托兒所收集所花費(fèi)的時(shí)間由需要復(fù)制的數(shù)據(jù)量決定。這不是說要復(fù)制的對(duì)象的數(shù)量與托兒所空間自身的大小沒有影響,而是說與復(fù)制實(shí)際數(shù)據(jù)的成本相比,這些因素造成的影響相對(duì)較小。因此,托兒所收集所花費(fèi)的時(shí)間與需要復(fù)制的數(shù)據(jù)量成正比。
- 在任何給定的收集中,只有有限和固定的數(shù)據(jù)量是 “實(shí)時(shí)的”。一旦應(yīng)用程序完成啟動(dòng)并完全填充其緩存后,托兒所堆中需要復(fù)制的 “實(shí)時(shí)” 數(shù)據(jù)量就由該時(shí)點(diǎn)需要完成的工作量來確定。在處理事務(wù)的系統(tǒng)中,需要復(fù)制的實(shí)時(shí)數(shù)據(jù)量等于某個(gè)實(shí)時(shí)事務(wù)集。例如,如果您使用支持 50 個(gè)并發(fā)事務(wù)發(fā)生的 50 個(gè) WebContainer 線程來配置您的應(yīng)用服務(wù)器,那么實(shí)時(shí)數(shù)據(jù)量就是與那 50 個(gè)事務(wù)關(guān)聯(lián)的數(shù)據(jù)量。
這意味著,托兒所收集所需的時(shí)間由收集時(shí)發(fā)生的并發(fā)事務(wù)的數(shù)量的關(guān)聯(lián)數(shù)據(jù)的大小決定,而不是由托兒所空間的大小決定。這還意味著,隨著托兒所空間的大小增大,托兒所收集之間的間隔時(shí)間會(huì)隨之增大,但收集所需的時(shí)間不會(huì)增加。事實(shí)上,隨著托兒所空間增大,垃圾收集所需的總時(shí)間會(huì)隨之降低。
圖 6 顯示,如果托兒所空間的大小低于事務(wù)集的關(guān)聯(lián)實(shí)時(shí)數(shù)據(jù)的大小,因此托兒所收集之間的時(shí)間間隔低于一個(gè)事務(wù),則必須多次復(fù)制這些數(shù)據(jù)。
圖 6. 數(shù)據(jù)復(fù)制的平均次數(shù)與托兒所收集之間的時(shí)間間隔

隨著托兒所空間大小和托兒所收集之間的時(shí)間間隔增加,需要復(fù)制的數(shù)據(jù)量通常會(huì)隨之減少,垃圾收集的開銷也會(huì)隨之降低。
IBM 垃圾收集器或 JVM 沒有對(duì)托兒所堆大小進(jìn)行直接限制;事實(shí)上,托兒所堆大小有時(shí)被設(shè)置為 10 GB 甚至 100 GB。但是,操作系統(tǒng)在 Java 進(jìn)程使用的虛擬內(nèi)存、進(jìn)程地址空間以及足夠的物理內(nèi)存(RAM)的可用性方面有一些限制。一個(gè) 32 位進(jìn)程在每個(gè)平臺(tái)上的操作系統(tǒng)限制如圖 7 所示。
圖 7. 按操作系統(tǒng)列示的 32 位地址空間

對(duì) 64 位進(jìn)程的限制要嚴(yán)格得多。由于可尋址內(nèi)存的范圍從數(shù)百到數(shù)十億 GB,可用物理內(nèi)存 (RAM) 的限制變得更加重要。
如上所述,最簡(jiǎn)單的方法是將托兒所空間視為一個(gè)額外的內(nèi)存空間。但是,托兒所堆和保留區(qū)堆實(shí)際上都被分配為單個(gè)連續(xù)內(nèi)存段,它們的大小可通過 -Xmx
設(shè)置進(jìn)行控制。如果只使用 -Xmx
設(shè)置,則 -Xmx
值的 25% 用于最大托兒所堆大小,托兒所堆大小允許在那 25% 之內(nèi)進(jìn)行伸縮。下面提供了 Java 堆布局,如圖 8 所示。
圖 8. 默認(rèn)堆布局

但是,您應(yīng)該將托兒所堆大小固定為一個(gè)較大的值,以最小化垃圾收集花費(fèi)的時(shí)間,增強(qiáng)保留區(qū)堆,使其根據(jù)占用率重置自身大小,從而提高彈性。因此,首選的 Java 堆布局如圖 9 所示。
圖 9. 推薦的堆布局

要實(shí)現(xiàn)這個(gè)布局,托兒所空間和保留區(qū)空間的最小和最大堆大小的值應(yīng)該設(shè)置如下:各個(gè)托兒所空間大小的最大和最小值都相等,而各個(gè)保留區(qū)空間大小的最小和最大值各不相同。
例如,如果您想擁有一個(gè) 256MB 的托兒所堆大小,而保留區(qū)堆大小介于 756MB 和 1024MB 之間,則這些值應(yīng)該為:
-Xmns256M
-Xmnx256M
-Xmos756M
-Xmox1024M
由于 WebSphere Application Server V8 中的默認(rèn) GC 策略已經(jīng)從 optthruput 變?yōu)?gencon,因此需要調(diào)整以前選擇的調(diào)優(yōu)參數(shù)。主要問題是更改堆大小來補(bǔ)償托兒所空間。以前在 optthruput 策略中,以 1G 堆大小(即 -Xmx1G
)運(yùn)行正常的程序在使用 768M 保留區(qū)空間和 256M 托兒所空間運(yùn)行時(shí)可能會(huì)出現(xiàn)問題。前面介紹的技術(shù)將有助于您選擇新的堆參數(shù)。
還有一些不太明顯的情況,gencon 可能會(huì)表現(xiàn)出不同的行為。
由于類通常是長(zhǎng)期存活的對(duì)象,因此可以將它們直接分配到保留區(qū)空間。因此,類卸載只能是保留區(qū)收集的一部分。如果應(yīng)用程序非常依賴短期存活的類加載器,且托兒所收集能夠及時(shí)處理其他已分配對(duì)象,那么保留區(qū)收集可能不會(huì)頻繁發(fā)生。這意味著,類和類加載器的數(shù)量將持續(xù)增長(zhǎng),這可能會(huì)增加本機(jī)內(nèi)存上的壓力,而且會(huì)在需要進(jìn)行保留區(qū)收集時(shí)導(dǎo)致收集時(shí)間過長(zhǎng),這是因?yàn)橛刑嗟念愋遁d工作需要完成。
如果出現(xiàn)這個(gè)問題,有兩種解決方法。第一種方法是在出現(xiàn)大量類加載器時(shí)鼓勵(lì)進(jìn)行額外的保留區(qū)收集。命令行選項(xiàng) -Xgc:classUnloadingKickoffThreshold=<number>
告知系統(tǒng),每當(dāng)新創(chuàng)建的類加載器達(dá)到 <number>
時(shí),就會(huì)啟動(dòng)一次并發(fā)保留區(qū)收集。因此,如果指定 -Xgc:classUnloadingKickoffThreshold=100
,那么托兒所收集會(huì)仔細(xì)觀察,每當(dāng)自上次保留區(qū)收集以來新創(chuàng)建的類加載器數(shù)量達(dá)到 100 時(shí),就會(huì)啟動(dòng)一次并發(fā)保留區(qū)收集。第二種方法是改為使用另一種 GC 策略。
類似的問題可能會(huì)出現(xiàn)在引用對(duì)象(例如 java.lang.ref.Reference
的子類)和使用 finalize()
方法的對(duì)象上。如果這兩種對(duì)象存活的時(shí)間足夠長(zhǎng),在變得無法訪問之前被移動(dòng)到保留區(qū)空間中,那么可能會(huì)經(jīng)過很長(zhǎng)時(shí)間以后才會(huì)運(yùn)行保留區(qū)收集,“發(fā)現(xiàn)” 這個(gè)對(duì)象已經(jīng)死亡。如果這些對(duì)象占用著大型或稀有本機(jī)資源,就有可能導(dǎo)致出現(xiàn)問題。我們將這種對(duì)象戲稱為 “冰山” 對(duì)象:表面上它們只占用很小的 Java 堆大小,但下面隱藏著巨大的本機(jī)資源,垃圾收集器看不到。就像面對(duì)真正的冰山一樣,最好的策略是盡可能遠(yuǎn)離它們。即使使用其他 GC 策略,也無法保證能夠探測(cè)到可終結(jié)的對(duì)象,并及時(shí)運(yùn)行它的終止程序 (finalizer)。如果它們占用稀有資源,盡可能地手動(dòng)釋放它們可能是最佳策略。
默認(rèn)策略應(yīng)該能為多數(shù)工作負(fù)載提供足夠的性能,但它可能不是某個(gè)特殊應(yīng)用程序的理想選擇。
類似 “批作業(yè)” 的應(yīng)用程序初始化狀態(tài)并加載要處理的數(shù)據(jù)。這些對(duì)象中的大部分將在作業(yè)期間存活,只有少數(shù)幾個(gè)額外對(duì)象是在作業(yè)運(yùn)行時(shí)創(chuàng)建的。 這種工作負(fù)載適合 optthruput 模式,因?yàn)轭A(yù)期的情況是:在任務(wù)完成之前,幾乎沒有垃圾。另一種類似情況是,如果作業(yè)很快完成或只分配很少的對(duì)象,那么只要堆大小適當(dāng),作業(yè)運(yùn)行就不需要垃圾收集。在上述這些情況下,optthruput 收集器的最小開銷會(huì)讓您做出最佳選擇。
相比之下,事務(wù)型應(yīng)用程序不斷創(chuàng)建并啟用對(duì)象組。在這個(gè)上下文中,術(shù)語 “事務(wù)” 主要使用字面意義(比如數(shù)據(jù)庫更新或電子商務(wù)采購(gòu))或者采用更寬泛的意義,比如一項(xiàng)獨(dú)立工作。舉例來說,服務(wù)一個(gè) Web 頁可以視為一個(gè)事務(wù)??蛻魴C(jī)提交一個(gè) URL,服務(wù)器計(jì)算頁面內(nèi)容并將其發(fā)送給客戶機(jī)。一旦客戶機(jī)接收到頁面,服務(wù)器就可以丟棄已計(jì)算的數(shù)據(jù)。
為了進(jìn)一步闡述這個(gè)定義,我們來看一個(gè)標(biāo)準(zhǔn)用戶界面。用戶單擊 Save 按鈕之后,系統(tǒng)會(huì)打開一個(gè)文件對(duì)話框,以便用戶導(dǎo)航文件系統(tǒng),為文檔選擇一個(gè)位置。一旦用戶關(guān)閉對(duì)話框,就不再需要所有中間狀態(tài)。實(shí)質(zhì)上,有些批作業(yè)甚至也是事務(wù)型的。假設(shè)一個(gè)任務(wù)正在為一些大型圖像文件創(chuàng)建縮略圖,那么該作業(yè)看起來似乎是一個(gè)大型批作業(yè),但在內(nèi)部,作業(yè)分別處理每個(gè)圖像,每個(gè)處理都形成一個(gè) “事務(wù)”。對(duì)于這類工作負(fù)載,gencon 模式應(yīng)該能提供好處。
optavgpause 模式介于二者之間。這種模式適用的應(yīng)用程序的特點(diǎn)是:擁有大量長(zhǎng)期存活的數(shù)據(jù),這些數(shù)據(jù)隨著程序運(yùn)行緩慢更改。對(duì)于工作負(fù)載而言,這種模式比較少見。通常,長(zhǎng)期存活的數(shù)據(jù)要么從不更改,要么頻繁更改。也就是說,如果系統(tǒng)擁有緩慢演變的數(shù)據(jù),且這些數(shù)據(jù)創(chuàng)建的中間對(duì)象也不多,那么這種系統(tǒng)就適合使用這個(gè)策略。由于前面討論的某種原因而不能在 gencon 策略下有效運(yùn)行的程序可能會(huì)受益于 optavgpause 的并發(fā)性。
本文簡(jiǎn)要描述了 WebSphere Application Server V8 中的 Java Virtual Machine 中提供的垃圾收集策略。盡管默認(rèn)設(shè)置應(yīng)該適用于多數(shù)情況,但是,為了獲得最佳性能,可能需要進(jìn)行一些調(diào)優(yōu)。通過匹配工作負(fù)載類型及其使用的 GC 策略并選擇適當(dāng)?shù)亩褏?shù),應(yīng)該能夠減少垃圾收集對(duì)應(yīng)用程序的影響。
本系列第 2 部分將介紹一種基于區(qū)域的新的垃圾收集策略 balanced,該策略旨在在 64 位大型多核系統(tǒng)上部署時(shí)提高可伸縮性。下一篇文章會(huì)涉及到這種新技術(shù)背后的動(dòng)機(jī)、它提供的性能改進(jìn)以及關(guān)于調(diào)優(yōu)這個(gè)新選項(xiàng)的提示和技巧。
學(xué)習(xí)
- Wikipedia: 垃圾收集定義
-
Java 技術(shù),IBM 風(fēng)格: 垃圾收集策略,第 1 部分
-
Java 技術(shù),IBM 風(fēng)格: 垃圾收集策略,第 2 部分
-
IBM developerWorks WebSphere
獲得產(chǎn)品和技術(shù)
-
下載 IBM SDKs for Java
-
IBM Monitoring and Diagnostic Tools for Java - Health Center
-
IBM Monitoring and Diagnostic Tools for Java - Garbage Collection and Memory Vizualiser
- IBM developerWorks 工具包:下載關(guān)鍵 WebSphere 最新的產(chǎn)品工具包。
討論
- 加入 developerWorks 中文社區(qū),developerWorks 社區(qū)是一個(gè)面向全球 IT 專業(yè)人員,可以提供博客、書簽、wiki、群組、聯(lián)系、共享和協(xié)作等社區(qū)功能的專業(yè)社交網(wǎng)絡(luò)社區(qū)。
- 加入 IBM 軟件下載與技術(shù)交流群組,參與在線交流。

Chris Bailey 是位于英國(guó)的 Hursley Park Development Lab 的 IBM Java Technology Center 團(tuán)隊(duì)成員。作為 IBM Java 服務(wù)和支持組織的技術(shù)架構(gòu)師,他負(fù)責(zé)支持 IBM SDK for Java 用戶交付成功的應(yīng)用程序部署。Chris 還參與收集和評(píng)估新需求,交付新調(diào)試功能和工具,改進(jìn)文檔并提高 IBM SDK for Java 的質(zhì)量。
Charlie Gracie 是位于加拿大的渥太華實(shí)驗(yàn)室的 IBM Java Technology Center 的團(tuán)隊(duì)成員。他畢業(yè)于 New Brunswick 大學(xué),從那里獲得了理學(xué)學(xué)士學(xué)位,并于 2004 年加入 J9 Virtual Machine 團(tuán)隊(duì)。他目前是 J9 Garbage Collection 團(tuán)隊(duì)的團(tuán)隊(duì)領(lǐng)導(dǎo),負(fù)責(zé)為 IBM JVM 提供所有垃圾收集技術(shù)。工作之余,Charlie 喜歡玩室內(nèi)和沙灘排球,熱衷于參加各種戶外活動(dòng)。
Karl Taylor 是位于加拿大的渥太華實(shí)驗(yàn)室的 IBM Java Technology Center 團(tuán)隊(duì)的團(tuán)隊(duì)成員。他擁有 Carleton University 頒發(fā)的理學(xué)學(xué)士學(xué)位,自從 J9 Virtual Machine 項(xiàng)目啟動(dòng)以來,他參與了該項(xiàng)目的多項(xiàng)工作。目前,他是 J9 Garbage Collection 團(tuán)隊(duì)的高級(jí)開發(fā)人員,還參與了 IBM 的 JSR 292 和 335 研發(fā)。工作之余,Karl 是一位葡萄酒愛好者,目前正在努力通過 Sommelier 認(rèn)證。