久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

關(guān)注性能: 調(diào)優(yōu)垃圾收集(Java)

 9loong 2010-04-12
http://www.ibm.com/developerworks/cn/java/j-perf06304/

將 100 MB 的垃圾打包成 50 MB 的包

級(jí)別: 初級(jí)

Jack Shirazi ([email protected]), 董事, JavaPerformanceTuning.com
Kirk Pepperdine ([email protected]), CTO, JavaPerformanceTuning.com

2004 年 7 月 30 日

如 果您是當(dāng)前寫網(wǎng)志(blogging)狂熱者中的一員,,則可能聽說過 Blog-City,,這是由蘇格蘭的一家小公司 Blog-City Ltd. 擁有和運(yùn)營的網(wǎng)志站點(diǎn)。當(dāng)一些意料之外的性能問題突然出現(xiàn)時(shí),,Java 性能專家 Jack Shirazi 和 Kirk Pepperdine 被邀請幫助進(jìn)行 Blog-City 的技術(shù)調(diào)整,。他們的檢測工作因?yàn)槭苡布s束和整個(gè)項(xiàng)目所使用的通信通道(IRC、ftp 和 偶爾的電子郵件)的限制而變得復(fù)雜,。

隨著網(wǎng)志作為公共日記的流行,,網(wǎng)志主機(jī)迅速地增長。所以對于 Blog-City 的人來說,,非常清楚他們的站點(diǎn)需要發(fā)展和提高,。為了滿足其增長的需要,該公司最近剛剛推出了 Blog-City version 2.0,。正像經(jīng)常出現(xiàn)的情況那樣,,當(dāng)新的應(yīng)用程序轉(zhuǎn)入運(yùn)行階段時(shí),由于各種原因,,其性能無法完全滿足期望的要求,,突然出現(xiàn)隨機(jī)的長時(shí)間應(yīng)用程序被掛起的現(xiàn) 象還不是最壞的情況。

在其核心,,Blog-City 依靠 Blue Dragon Servlet 引擎(CFML 引擎)和數(shù)據(jù)庫,。令人驚訝的是,所有這些軟件都宿主在運(yùn)行 Red Hat Linux 的相當(dāng)老的 P3 機(jī)器上,。這臺(tái)機(jī)器具有單個(gè)硬盤和 512MB 內(nèi)存,,這對于過去的負(fù)載來說是足夠強(qiáng)大的,但它正在承受不斷增長的負(fù)載,。Blog-City 的運(yùn)作方式很成功,,但其資源限制卻成了其成功路上的絆腳石。盡管如此,,這就是未來還要繼續(xù)使用一段時(shí)間的所有硬件,。

問題定義

整個(gè)過程的第一步是確定突然出現(xiàn)應(yīng)用程序減慢的原因。首先我們懷疑的對象是垃圾收集,。正如我們在 本 專欄的上月文章 中所論述的那樣,,確定垃圾收集和內(nèi)存利用問題是否對應(yīng)用程序產(chǎn)生負(fù)面影響的最容易的方式是,設(shè)置 -verbose:gc JVM 選項(xiàng),,并檢查日志輸出,。因此我們重新啟動(dòng)應(yīng)用程序,,打開冗長的垃圾收集日志選項(xiàng),然后耐心地等待應(yīng)用程序的性能降低,。我們的耐心換來的是非常詳細(xì)的垃圾收 集日志文件,。

從對日志文件的最初分析中看,在這一應(yīng)用程序中垃圾收集的瓶頸是顯而易見的,。種種跡象包括垃圾收集的頻率,、持續(xù)時(shí)間和總體效率都已表明 這一點(diǎn)。高于普通垃圾收集頻率的常見原因是,,堆的大小剛好足以適應(yīng)所有當(dāng)前正在使用的運(yùn)行對象,,無法適應(yīng)新的正被創(chuàng)建的對象。雖然應(yīng)用程序消耗大量堆可能 有許多原因,,但主要原因可能是沒有足夠內(nèi)存而導(dǎo)致垃圾收集器運(yùn)行,,因?yàn)樗O(shè)法滿足當(dāng)前需要。換句話說,,應(yīng)用程序試圖分配新對象,,但失敗了,如果失敗的話,, 將觸發(fā)垃圾收集程序,。如果垃圾收集失敗而無法恢復(fù)足夠內(nèi)存,它將迫使另一個(gè)花費(fèi)更大的垃圾收集程序發(fā)生,。即使 GC 恢復(fù)了足夠的空間來滿足瞬間需求,,可以肯定的是,在應(yīng)用程序程序另一次分配失敗,,觸發(fā)另一個(gè) GC 之前,,時(shí)間不會(huì)很長。因此,,應(yīng)該關(guān)注重復(fù)掃描空閑堆空間的無效任務(wù),,而不是服務(wù)于應(yīng)用程序的 JVM。

應(yīng)用程序逐步消耗所有可用的堆空間可能有許多原因,,但如果有更多內(nèi)存的話,,臨時(shí)解決方案就是配置更大的堆。假設(shè)應(yīng)用程序沒有內(nèi)存泄漏 (或者也就是我們常說的“無意識(shí)地保留對象”),,它將找到一個(gè)“自然”級(jí)別的堆消耗,,在這個(gè)級(jí)別中,GC 將能夠很適應(yīng)地得到維持(除非對象創(chuàng)建的速度過快,,以至 GC 總是處于賽跑狀態(tài)),。在這種情況下,以及無意識(shí)地保留對象的情況下,,我們需要對應(yīng)用程序做一些變動(dòng),,以便獲得某些改進(jìn)。





回頁首


如果僅僅是這樣,,那就太簡單了

遺憾的是,,我們必須面對嚴(yán)酷的現(xiàn)實(shí)因素——正在運(yùn)行的機(jī)器只有 512 MB 內(nèi)存。更糟的是,,我們必須與數(shù)據(jù)庫和其他運(yùn)行在機(jī)器中的進(jìn)程共享該空間,。要完整理解這一點(diǎn)為什么至關(guān)重要,首先您必須明確理解垃圾收集的基本知識(shí),,以及它 如何與底層操作系統(tǒng)進(jìn)行交互,。

虛擬內(nèi)存不再是靈丹妙藥

操作系統(tǒng)已經(jīng)使用虛擬內(nèi)存許多年了。正如您所知道的,,虛擬內(nèi)存使操作系統(tǒng)的內(nèi)存看起來比實(shí)際的內(nèi)存要多,,這允許計(jì)算機(jī)運(yùn)行那些所需內(nèi)存 比可用物理內(nèi)存更大的程序,不使用內(nèi)存的應(yīng)用程序部分將保存在磁盤上,。為了進(jìn)一步簡化,,操作系統(tǒng)同時(shí)按頁管理內(nèi)存。頁通常包含 512 字節(jié)到 8 KB,,所有頁的組合就組成了一個(gè)虛擬地址空間,。操作系統(tǒng)維持一個(gè)頁表,用于告訴操作系統(tǒng)如何映射虛擬地址到物理地址,。當(dāng)應(yīng)用程序要求某個(gè)內(nèi)存位置的內(nèi)容 時(shí),,操作系統(tǒng)(或硬件)將識(shí)別包含虛擬地址的頁面。然后確定該頁面是否在內(nèi)存中,,如果不在,,將會(huì)報(bào)告 頁面錯(cuò)誤。但是有許多種方式來處理頁面錯(cuò)誤,,最終的結(jié)果是,,頁面必須從磁盤載入到內(nèi)存中。這樣應(yīng)用程序就可以訪問到有效虛 擬地址的內(nèi)容,。

如果相關(guān)對象總是在內(nèi)存的同一頁面上聚合,,那么 GC 的連續(xù)工作很可能出現(xiàn)困難。但是現(xiàn)實(shí)世界中,,相關(guān)對象很少(如果有的話)出現(xiàn)聚合現(xiàn)象,。實(shí)際結(jié)果是,依靠虛擬內(nèi)存的系統(tǒng)將導(dǎo)致操作系統(tǒng)將頁從內(nèi)存中換入和 換出,,因?yàn)樗鼧?biāo)記然后廢棄堆空間,,而當(dāng)聚合現(xiàn)象發(fā)生時(shí),GC 將很多時(shí)間花在等待頁面從磁盤換入而不是實(shí)際恢復(fù)內(nèi)存上,。因此,,應(yīng)用程序正在等待 GC,,而 GC 正在等待磁盤,其間未完成任何真正的工作,。由于本系統(tǒng)只有一個(gè)磁盤,,并且它還需要支持?jǐn)?shù)據(jù)庫,因此我們在解決問題時(shí)處于兩難境地,。一方面,,我們需要增加內(nèi) 存數(shù)量,這樣我們可以減少 GC 的頻率,,但另一方面,,我們還需要確保數(shù)據(jù)庫的完好運(yùn)行,而數(shù)據(jù)庫也是內(nèi)存的消耗大戶,。因此,,我們需要了解應(yīng)用程序所需的最小內(nèi)存數(shù)量。

正如我們在上月看到的,,在冗長的 GC 日志中這一信息可以很容易得到,,無需為這一信息而掃描整個(gè)日志,我們使用免費(fèi)的 JTune 工具(請參閱 參 考資料)來解釋冗長的 GC 日志,。圖 1 顯示了經(jīng)過垃圾收集之后的內(nèi)存利用情況,,其中我們將 -Xmx 設(shè)置為 256 MB。


圖 1. 垃圾收集之后的內(nèi)存利用情況
圖 1. 垃圾收集之后的內(nèi)存利用情況




回頁首


分析 verbose:gc 輸出

在圖 1 中,,藍(lán)色部分表示部分 GC,。橙色區(qū)域表示完整的 GC,而粉色矩形表示兩個(gè)完整 GC 在它們之間少于一毫秒之內(nèi)已經(jīng)發(fā)生的堆利用情況,。從結(jié)果中我們看到,,平均每 0.257 秒有 12,823 次清除??偣灿?345 次完整的垃圾收集和 44 次緊挨著的垃圾收集,。完整垃圾收集的平均持續(xù)時(shí)間是 7.303 秒,結(jié)果表明有 9.36% 的運(yùn)行時(shí)間花費(fèi)在垃圾收集程序上,。雖然這個(gè)值偏高,,它仍然保持在 10% 的正常水平之內(nèi)。因此,,在本例中,,GC 是系統(tǒng)的繁重負(fù)擔(dān)但還沒有達(dá)到嚴(yán)重的地步。真正的問題是存在內(nèi)存泄漏,,這一點(diǎn)可以從總體上堆利用率不斷增長的趨勢看出來,。

即使內(nèi)存泄漏消耗了 50 MB 內(nèi)存,它也應(yīng)該是經(jīng)過很長一段時(shí)間后才發(fā)生,這使得內(nèi)存泄漏在較短的測試中很少會(huì)引人注意,。內(nèi)存泄漏的實(shí)際結(jié)果是,,它把 JVM 的內(nèi)存消耗推動(dòng)到某個(gè)點(diǎn),在該點(diǎn)它強(qiáng)迫 JVM (從而強(qiáng)迫操作系統(tǒng))消耗內(nèi)存,,它強(qiáng)迫啟動(dòng)分頁,。圖 2 就證明了這一點(diǎn),。注意正好在 55,000 秒標(biāo)記之后,,每一 GC 周期的持續(xù)時(shí)間中內(nèi)存消耗突然地持續(xù)增加。


圖 2. GC 持續(xù)時(shí)間
圖 2. gc 持續(xù)時(shí)間

如您所想,,由于垃圾收集的阻塞將導(dǎo)致系統(tǒng)只有更少的時(shí)間來分配給用戶線程,,因此用戶響應(yīng)開始增加。在日志的過去 10,000 秒中,,我們看到每次完全收集(總共 15 次)花費(fèi)時(shí)間超過了 30 秒,,平均持續(xù)時(shí)間大約 70 秒 —— 這導(dǎo)致超過 10% 的處理時(shí)間分配給完全 GC。部分收集(這里剛好超過了 1000 次)無法正常工作,,平均每次請求耗時(shí) 1.24 秒,,遠(yuǎn)高于以前 11,800 次清除中的平均 0.25 秒。

分代收集

本文不涉及太深的細(xì)節(jié)(請參閱 參 考資料,,獲取分代 GC 的詳細(xì)描述),,分代堆空間產(chǎn)生了“年輕”和“年老”對象,它們位于分開的堆空間中,。在本配置中,,年輕和年老分代空間可以通過不同的 GC 算法和策略來維持,以提高 GC 的整體性能,。

一種這樣的策略是,,進(jìn)一步將年輕分代劃分為創(chuàng)建空間,稱為 Eden,,以及殘存(survivor)空間,,用于幸存一個(gè)或者多個(gè)收集的年輕對象。如果在 Eden 中有足夠的內(nèi)存來適應(yīng)新對象創(chuàng)建的話,,這一般能工作正常,。如果不是這種情況,那么對象可以在年老對象空間中創(chuàng)建,。同樣,,如果殘存空間足夠的話,那么對象將 移入年老分代空間,。我們將使用這些事實(shí)來幫助調(diào)優(yōu)遇到的問題,。





回頁首


減少完全收集的次數(shù)

Blog-City 所碰到的難題是在某一隨機(jī)點(diǎn)出現(xiàn)長的暫停時(shí)間。一旦應(yīng)用程序啟動(dòng)出現(xiàn)問題,不重新啟動(dòng)機(jī)器的話,,就無法返回跟蹤,。由于長時(shí)間暫停的現(xiàn)象直接與長的 GC 相關(guān),我們考慮如果將對象保持在年輕分代來減少完全 GC 的次數(shù),。由于完全 GC 的代價(jià)如此之大,,在年輕分代收集更多對象能夠得到更短的暫停時(shí)間。要完成這一任務(wù),,我們調(diào)整了一些垃圾收集參數(shù),,包括 殘存比率(survivor ratio)期限閾值(tenuring threshold)

殘存比率用于設(shè)置與年輕分代空間總體大小相關(guān)的殘存空間的大小,。如果殘存比率設(shè)置為 8(Intel 的默認(rèn)值),,那么每一殘存空間將是 Eden 空間的 1/8 大小。另一種考察它的方式是,,年輕分代將該 Eden 空間劃分為 10 個(gè)相同大小的值,,該 Eden 將分配其中的 8 個(gè),每一個(gè)殘存空間的大小為 1,。

我們的假設(shè)是,,通過減少殘存比率,我們可以減少由于殘存空間中空間的缺乏,,對象過早地被提升為年老分代的幾率,。另一種方法是增加期限閾 值,這樣的話,,對象在提升之前將需要保留更多的 GC 事件,。本著這個(gè)想法,Blog-City 將設(shè)置更改為 -XX:SurvivorRatio=4 ,,然后重新啟動(dòng),。

選擇低暫停時(shí)間的垃圾收集算法

由于這次技術(shù)調(diào)優(yōu)的目標(biāo)之一是減少暫停時(shí)間,我們決定拋棄默認(rèn)的單線程,、標(biāo)記清掃的垃圾收集程序,。我們選擇通過標(biāo)志 XX:+UseParallelGC 來采用并行拷貝收集程序。同樣,,有關(guān)實(shí)際算法的細(xì)節(jié)可以在 Resources中 找到,,這里需要提一下的是,這一標(biāo)志調(diào)用了一個(gè)多線程收集程序,。線程的數(shù)量設(shè)置為 CPU 的數(shù)量,。基于這一事實(shí),,了解為什么單線程并行拷貝垃圾收集程序要比傳統(tǒng)的標(biāo)記清掃算法工作更好是很困難的,,但是從實(shí)際觀察中可以體會(huì)到提供了某些性能上的 優(yōu)勢。

圖 3 和圖 4 的輸出展示了使用標(biāo)志 -XX:SurvivorRatio=4 +XX:+UseParallelGC -server -Xmx256M 運(yùn)行時(shí)的結(jié)果。


圖 3. 新配置下的內(nèi)存使用情況
圖 3. 新配置下的內(nèi)存使用情況

結(jié)果圖表顯示了明顯的不同,。雖然仍然有一個(gè)內(nèi)存漏洞,。內(nèi)存消耗的總數(shù)相比前一個(gè)圖已經(jīng)是大大降低了。GC 持續(xù)時(shí)間的快速比較揭示了年輕分代和年老分代的總體 GC 持續(xù)時(shí)間的明顯減少,。


圖 4. 新配置下的 GC 持續(xù)時(shí)間
圖 4. 新配置下的 gc 持續(xù)時(shí)間

有意的,、無意的對象保持

由于應(yīng)用程序是依靠內(nèi)存的,跟蹤內(nèi)存泄漏并消除它們已經(jīng)變得越來越重要,。在本例中,,用于支持緩存策略的組件決定了主要漏洞的來源。從最 后的內(nèi)存分析情況來看(圖 3),,雖然消除了主要內(nèi)存泄漏,,我們可以看到仍有另一個(gè)“低級(jí)別的”的漏洞,但這個(gè)漏洞比較小,,因此它在下一版本發(fā)布之前可以忽略。





回頁首


結(jié)束語

本文提出了許多挑戰(zhàn),。首先,,我們正在調(diào)優(yōu)一個(gè)現(xiàn)實(shí)中的應(yīng)用程序,這意味著更改會(huì)受到很多限制,。第二個(gè)挑戰(zhàn)是,,這項(xiàng)任務(wù)是使用 IRC 聊天室遠(yuǎn)程操控的。聊天室不提供任何級(jí)別或質(zhì)量的相互通信,,而通信在這種類型的任務(wù)中往往是必需的,。在本例中,團(tuán)隊(duì)已經(jīng)習(xí)慣了聊天室的真實(shí)性,,并能通過這 種真實(shí)性毫無任何阻礙地工作著,。

最后也是最困難的挑戰(zhàn)是我們受硬件的限制。由于多種原因,,我們不可能為系統(tǒng)添加新硬件,。其中最大的問題是系統(tǒng)中物理內(nèi)存的數(shù)量,而 JVM 和 MySQL 需要大量的內(nèi)存,。但是,,通過系統(tǒng)地逐一應(yīng)用許多更改,并度量它們對系統(tǒng)產(chǎn)生的影響,,我們可以逐步地改進(jìn)總體系統(tǒng)性能,。



參考資料



作者簡介


Jack Shirazi 是 JavaPerformanceTuning.com的 董事和 Java Performance Tuning, 2nd Edition (O'Reilly) 一書的作者。



Kirk Pepperdine is 是 Java Performance Tuning.com 的首席技術(shù)官(Chief Technical Officer,,CTO),,過去 15 年來他一直專攻對象技術(shù)和性能調(diào)優(yōu)。Kirk 是 Ant Developer's Handbook (MacMillan) 一書的合著者,。



(#)

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多