JVM實(shí)用參數(shù)(六) 吞吐量收集器

原文鏈接
本文連接
譯者:張軍 校對:梁海艦

在實(shí)踐中我們發(fā)現(xiàn)對于大多數(shù)的應(yīng)用領(lǐng)域笙纤,評估一個(gè)垃圾收集(GC)算法如何根據(jù)如下兩個(gè)標(biāo)準(zhǔn):

  • 吞吐量越高算法越好
  • 暫停時(shí)間越短算法越好

首先讓我們來明確垃圾收集(GC)中的兩個(gè)術(shù)語:吞吐量(throughput)和暫停時(shí)間(pause times)画恰。 JVM在專門的線程(GC threads)中執(zhí)行GC姊氓。 只要GC線程是活動的卒暂,它們將與應(yīng)用程序線程(application threads)爭用當(dāng)前可用CPU的時(shí)鐘周期青自。 簡單點(diǎn)來說洞辣,吞吐量是指應(yīng)用程序線程用時(shí)占程序總用時(shí)的比例仑荐。 例如,吞吐量99/100意味著100秒的程序執(zhí)行時(shí)間應(yīng)用程序線程運(yùn)行了99秒伪阶, 而在這一時(shí)間段內(nèi)GC線程只運(yùn)行了1秒煞檩。

術(shù)語”暫停時(shí)間”是指一個(gè)時(shí)間段內(nèi)應(yīng)用程序線程讓與GC線程執(zhí)行而完全暫停。 例如栅贴,GC期間100毫秒的暫停時(shí)間意味著在這100毫秒期間內(nèi)沒有應(yīng)用程序線程是活動的斟湃。 如果說一個(gè)正在運(yùn)行的應(yīng)用程序有100毫秒的“平均暫停時(shí)間”,那么就是說該應(yīng)用程序所有的暫停時(shí)間平均長度為100毫秒檐薯。 同樣凝赛,100毫秒的“最大暫停時(shí)間”是指該應(yīng)用程序所有的暫停時(shí)間最大不超過100毫秒。

吞吐量 VS 暫停時(shí)間

高吞吐量最好因?yàn)檫@會讓應(yīng)用程序的最終用戶感覺只有應(yīng)用程序線程在做“生產(chǎn)性”工作坛缕。 直覺上哄酝,吞吐量越高程序運(yùn)行越快。 低暫停時(shí)間最好因?yàn)閺淖罱K用戶的角度來看不管是GC還是其他原因?qū)е乱粋€(gè)應(yīng)用被掛起始終是不好的祷膳。 這取決于應(yīng)用程序的類型,有時(shí)候甚至短暫的200毫秒暫停都可能打斷終端用戶體驗(yàn)屡立。 因此直晨,具有低的最大暫停時(shí)間是非常重要的,特別是對于一個(gè)交互式應(yīng)用程序膨俐。

不幸的是”高吞吐量”和”低暫停時(shí)間”是一對相互競爭的目標(biāo)(矛盾)勇皇。這樣想想看,為了清晰起見簡化一下:GC需要一定的前提條件以便安全地運(yùn)行焚刺。 例如敛摘,必須保證應(yīng)用程序線程在GC線程試圖確定哪些對象仍然被引用和哪些沒有被引用的時(shí)候不修改對象的狀態(tài)。 為此乳愉,應(yīng)用程序在GC期間必須停止(或者僅在GC的特定階段兄淫,這取決于所使用的算法)屯远。 然而這會增加額外的線程調(diào)度開銷:直接開銷是上下文切換,間接開銷是因?yàn)榫彺娴挠绊憽?加上JVM內(nèi)部安全措施的開銷捕虽,這意味著GC及隨之而來的不可忽略的開銷慨丐,將增加GC線程執(zhí)行實(shí)際工作的時(shí)間。 因此我們可以通過盡可能少運(yùn)行GC來最大化吞吐量泄私,例如房揭,只有在不可避免的時(shí)候進(jìn)行GC,來節(jié)省所有與它相關(guān)的開銷晌端。

然而捅暴,僅僅偶爾運(yùn)行GC意味著每當(dāng)GC運(yùn)行時(shí)將有許多工作要做,因?yàn)樵诖似陂g積累在堆中的對象數(shù)量很高咧纠。 單個(gè)GC需要花更多時(shí)間來完成蓬痒, 從而導(dǎo)致更高的平均和最大暫停時(shí)間。 因此惧盹,考慮到低暫停時(shí)間乳幸,最好頻繁地運(yùn)行GC以便更快速地完成。 這反過來又增加了開銷并導(dǎo)致吞吐量下降钧椰,我們又回到了起點(diǎn)粹断。
綜上所述,在設(shè)計(jì)(或使用)GC算法時(shí)??嫡霞,我們必須確定我們的目標(biāo):一個(gè)GC算法??只可能針對兩個(gè)目標(biāo)之一(即只專注于最大吞吐量或最小暫停時(shí)間)瓶埋,或嘗試找到一個(gè)二者的折衷。

HotSpot虛擬機(jī)上的垃圾收集

該系列的第五部分我們已經(jīng)討論過年輕代的垃圾收集器诊沪。 對于年老代养筒,HotSpot虛擬機(jī)提供兩類垃圾收集算法(除了新的G1垃圾收集算法),第一類算法試圖最大限度地提高吞吐量端姚,而第二類算法試圖最小化暫停時(shí)間晕粪。 今天我們的重點(diǎn)是第一類,”面向吞吐量”的垃圾收集算法渐裸。
我們希望把重點(diǎn)放在JVM配置參數(shù)上巫湘,所以我只會簡要概述HotSpot提供的面向吞吐量(throughput-oriented)垃圾收集算法。 當(dāng)年老代中由于缺乏空間導(dǎo)致對象分配失敗時(shí)會觸發(fā)垃圾收集器(事實(shí)上昏鹃,”分配”的通常是指從年輕代提升到年老代的對象)尚氛。 從所謂的”GC根”(GC roots)開始,搜索堆中的可達(dá)對象并將其標(biāo)記為活著的洞渤,之后阅嘶,垃圾收集器將活著的對象移到年老代的一塊無碎片(non-fragmented)內(nèi)存塊中,并標(biāo)記剩余的內(nèi)存空間是空閑的载迄。 也就是說讯柔,我們不像復(fù)制策略那樣移到一個(gè)不同的堆區(qū)域抡蛙,像年輕代垃圾收集算法所做的那樣。 相反地磷杏,我們把所有的對象放在一個(gè)堆區(qū)域中溜畅,從而對該堆區(qū)域進(jìn)行碎片整理。 垃圾收集器使用一個(gè)或多個(gè)線程來執(zhí)行垃圾收集极祸。 當(dāng)使用多個(gè)線程時(shí)慈格,算法的不同步驟被分解,使得每個(gè)收集線程大多時(shí)候工作在自己的區(qū)域而不干擾其他線程遥金。 在垃圾收集期間浴捆,所有的應(yīng)用程序線程暫停,只有垃圾收集完成之后才會重新開始稿械。 現(xiàn)在讓我們來看看跟面向吞吐量垃圾收集算法有關(guān)的重要JVM配置參數(shù)选泻。

-XX:+UseSerialGC

我們使用該標(biāo)志來激活串行垃圾收集器,例如單線程面向吞吐量垃圾收集器美莫。 無論年輕代還是年老代都將只有一個(gè)線程執(zhí)行垃圾收集页眯。 該標(biāo)志被推薦用于只有單個(gè)可用處理器核心的JVM。 在這種情況下厢呵,使用多個(gè)垃圾收集線程甚至?xí)m得其反窝撵,因?yàn)檫@些線程將爭用CPU資源,造成同步開銷襟铭,卻從未真正并行運(yùn)行碌奉。

-XX:+UseParallelGC

有了這個(gè)標(biāo)志,我們告訴JVM使用多線程并行執(zhí)行年輕代垃圾收集寒砖。 在我看來赐劣,Java 6中不應(yīng)該使用該標(biāo)志因?yàn)?XX:+UseParallelOldGC顯然更合適。 需要注意的是Java 7中該情況改變了一點(diǎn)(詳見本概述)哩都,就是-XX:+UseParallelGC能達(dá)到-XX:+UseParallelOldGC一樣的效果魁兼。

-XX:+UseParallelOldGC

該標(biāo)志的命名有點(diǎn)不巧,因?yàn)椤崩稀甭犉饋硐瘛边^時(shí)”漠嵌。 然而璃赡,”老”實(shí)際上是指年老代,這也解釋了為什么-XX:+UseParallelOldGC要優(yōu)于-XX:+UseParallelGC:除了激活年輕代并行垃圾收集献雅,也激活了年老代并行垃圾收集。 當(dāng)期望高吞吐量塌计,并且JVM有兩個(gè)或更多可用處理器核心時(shí)挺身,我建議使用該標(biāo)志。
作為旁注锌仅,HotSpot的并行面向吞吐量垃圾收集算法通常稱為”吞吐量收集器”章钾,因?yàn)樗鼈冎荚谕ㄟ^并行執(zhí)行來提高吞吐量墙贱。

-XX:ParallelGCThreads

通過-XX:ParallelGCThreads=<value>我們可以指定并行垃圾收集的線程數(shù)量。 例如贱傀,-XX:ParallelGCThreads=6表示每次并行垃圾收集將有6個(gè)線程執(zhí)行惨撇。 如果不明確設(shè)置該標(biāo)志,虛擬機(jī)將使用基于可用(虛擬)處理器數(shù)量計(jì)算的默認(rèn)值府寒。 決定因素是由Java Runtime魁衙。availableProcessors()方法的返回值N,如果N<=8剖淀,并行垃圾收集器將使用N個(gè)垃圾收集線程,如果N>8個(gè)可用處理器捌刮,垃圾收集線程數(shù)量應(yīng)為3+5N/8。
當(dāng)JVM獨(dú)占地使用系統(tǒng)和處理器時(shí)使用默認(rèn)設(shè)置更有意義。 但是,如果有多個(gè)JVM(或其他耗CPU的系統(tǒng))在同一臺機(jī)器上運(yùn)行役拴,我們應(yīng)該使用-XX:ParallelGCThreads來減少垃圾收集線程數(shù)到一個(gè)適當(dāng)?shù)闹怠?例如,如果4個(gè)以服務(wù)器方式運(yùn)行的JVM同時(shí)跑在在一個(gè)具有16核處理器的機(jī)器上,設(shè)置-XX:ParallelGCThreads=4是明智的,它能使不同JVM的垃圾收集器不會相互干擾妓湘。

-XX:-UseAdaptiveSizePolicy

吞吐量垃圾收集器提供了一個(gè)有趣的(但常見,至少在現(xiàn)代JVM上)機(jī)制以提高垃圾收集配置的用戶友好性。 這種機(jī)制被看做是HotSpot在Java 5中引入的”人體工程學(xué)”概念的一部分。 通過人體工程學(xué),垃圾收集器能將堆大小動態(tài)變動像GC設(shè)置一樣應(yīng)用到不同的堆區(qū)域驻龟,只要有證據(jù)表明這些變動將能提高GC性能凌蔬。 “提高GC性能”的確切含義可以由用戶通過-XX:GCTimeRatio和-XX:MaxGCPauseMillis(見下文)標(biāo)記來指定。
重要的是要知道人體工程學(xué)是默認(rèn)激活的坎弯。 這很好外永,因?yàn)樽赃m應(yīng)行為是JVM最大優(yōu)勢之一。 不過汪厨,有時(shí)我們需要非常清楚對于特定應(yīng)用什么樣的設(shè)置是最合適的劫乱,在這些情況下织中,我們可能不希望JVM混亂我們的設(shè)置。 每當(dāng)我們發(fā)現(xiàn)處于這種情況時(shí)衷戈,我們可以考慮通過-XX:-UseAdaptiveSizePolicy停用一些人體工程學(xué)狭吼。

-XX:GCTimeRatio

通過-XX:GCTimeRatio=<value>我們告訴JVM吞吐量要達(dá)到的目標(biāo)值。 更準(zhǔn)確地說殖妇,-XX:GCTimeRatio=N指定目標(biāo)應(yīng)用程序線程的執(zhí)行時(shí)間(與總的程序執(zhí)行時(shí)間)達(dá)到N/(N+1)的目標(biāo)比值刁笙。 例如,通過-XX:GCTimeRatio=9我們要求應(yīng)用程序線程在整個(gè)執(zhí)行時(shí)間中至少9/10是活動的(因此谦趣,GC線程占用其余1/10)疲吸。 基于運(yùn)行時(shí)的測量,JVM將會嘗試修改堆和GC設(shè)置以期達(dá)到目標(biāo)吞吐量前鹅。 -XX:GCTimeRatio的默認(rèn)值是99摘悴,也就是說,應(yīng)用程序線程應(yīng)該運(yùn)行至少99%的總執(zhí)行時(shí)間舰绘。

-XX:MaxGCPauseMillis

通過-XX:GCTimeRatio=<value>告訴JVM最大暫停時(shí)間的目標(biāo)值(以毫秒為單位)蹂喻。 在運(yùn)行時(shí),吞吐量收集器計(jì)算在暫停期間觀察到的統(tǒng)計(jì)數(shù)據(jù)(加權(quán)平均和標(biāo)準(zhǔn)偏差)捂寿。 如果統(tǒng)計(jì)表明正在經(jīng)歷的暫停其時(shí)間存在超過目標(biāo)值的風(fēng)險(xiǎn)時(shí)口四,JVM會修改堆和GC設(shè)置以降低它們。 需要注意的是者蠕,年輕代和年老代垃圾收集的統(tǒng)計(jì)數(shù)據(jù)是分開計(jì)算的窃祝,還要注意,默認(rèn)情況下踱侣,最大暫停時(shí)間沒有被設(shè)置粪小。
如果最大暫停時(shí)間和最小吞吐量同時(shí)設(shè)置了目標(biāo)值,實(shí)現(xiàn)最大暫停時(shí)間目標(biāo)具有更高的優(yōu)先級抡句。 當(dāng)然探膊,無法保證JVM將一定能達(dá)到任一目標(biāo),即使它會努力去做待榔。 最后逞壁,一切都取決于手頭應(yīng)用程序的行為流济。
當(dāng)設(shè)置最大暫停時(shí)間目標(biāo)時(shí),我們應(yīng)注意不要選擇太小的值腌闯。 正如我們現(xiàn)在所知道的绳瘟,為了保持低暫停時(shí)間,JVM需要增加GC次數(shù)姿骏,那樣可能會嚴(yán)重影響可達(dá)到的吞吐量糖声。 這就是為什么對于要求低暫停時(shí)間作為主要目標(biāo)的應(yīng)用程序(大多數(shù)是Web應(yīng)用程序),我會建議不要使用吞吐量收集器分瘦,而是選擇CMS收集器蘸泻。 CMS收集器是本系列下一部分的主題。

轉(zhuǎn)載自
并發(fā)編程網(wǎng) – ifeve.com
轉(zhuǎn)載鏈接地址:
JVM實(shí)用參數(shù)(六) 吞吐量收集器

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嘲玫,一起剝皮案震驚了整個(gè)濱河市悦施,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌去团,老刑警劉巖抡诞,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異渗勘,居然都是意外死亡沐绒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門旺坠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乔遮,“玉大人,你說我怎么就攤上這事取刃√0梗” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵璧疗,是天一觀的道長坯辩。 經(jīng)常有香客問我,道長崩侠,這世上最難降的妖魔是什么漆魔? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮却音,結(jié)果婚禮上改抡,老公的妹妹穿的比我還像新娘。我一直安慰自己系瓢,他們只是感情好阿纤,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著夷陋,像睡著了一般欠拾。 火紅的嫁衣襯著肌膚如雪胰锌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天藐窄,我揣著相機(jī)與錄音资昧,去河邊找鬼。 笑死荆忍,一個(gè)胖子當(dāng)著我的面吹牛榛搔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播东揣,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼腹泌!你這毒婦竟也來了嘶卧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤凉袱,失蹤者是張志新(化名)和其女友劉穎芥吟,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體专甩,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钟鸵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涤躲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棺耍。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖种樱,靈堂內(nèi)的尸體忽然破棺而出蒙袍,到底是詐尸還是另有隱情,我是刑警寧澤嫩挤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布害幅,位于F島的核電站,受9級特大地震影響岂昭,放射性物質(zhì)發(fā)生泄漏以现。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一约啊、第九天 我趴在偏房一處隱蔽的房頂上張望邑遏。 院中可真熱鬧,春花似錦棍苹、人聲如沸无宿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽孽鸡。三九已至蹂午,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間彬碱,已是汗流浹背豆胸。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留巷疼,地道東北人晚胡。 一個(gè)月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像嚼沿,于是被迫代替她去往敵國和親估盘。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 原文閱讀 前言 這段時(shí)間懈怠了骡尽,罪過遣妥! 最近看到有同事也開始用上了微信公眾號寫博客了,挺好的~給他們點(diǎn)贊攀细,這博客我...
    碼農(nóng)戲碼閱讀 5,952評論 2 31
  • 1.一些概念 1.1.數(shù)據(jù)類型 Java虛擬機(jī)中箫踩,數(shù)據(jù)類型可以分為兩類:基本類型和引用類型√诽埃基本類型的變量保存原始...
    落落落落大大方方閱讀 4,524評論 4 86
  • Java 虛擬機(jī)有自己完善的硬件架構(gòu), 如處理器境钟、堆棧、寄存器等俭识,還具有相應(yīng)的指令系統(tǒng)慨削。JVM 屏蔽了與具體操作系...
    尹小凱閱讀 1,684評論 0 10
  • 原文連接轉(zhuǎn)載連接譯者: iDestiny 校對:梁海艦 HotSpot JVM的并發(fā)標(biāo)記清理收集器(CMS收集器...
    低至一折起閱讀 691評論 0 2
  • 轉(zhuǎn)載blog.csdn.net/ning109314/article/details/10411495/ JVM工...
    forever_smile閱讀 5,353評論 1 56