java jvm调优_(第2部分,共3部分):有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的摘要...
java jvm調(diào)優(yōu)
這是以前的文章(第3部分,共1部分)的繼續(xù):有關(guān)性能調(diào)優(yōu),Java中的JVM,GC,Mechanical Sympathy等的文章和視頻的提要 。
事不宜遲,讓我們開始使用我們的下一組博客和視頻,斬……斬……! 這一次是Martin Thompson的博客文章和討論。 馬丁關(guān)于Java垃圾收集的第一篇文章基本上是精簡了GC流程及其底層組件,包括將光投向許多有趣的GC標志( -XX:… )。 在他的下一次演講中,他講述了機械同情,人們正確相信的東西以及誤解的神話。 在性能測試的討論中,Martin進一步完善了Java,OS和硬件的融合,以展示對所有這些方面的理解如何有助于編寫更好的程序。
Martin Thompson
標志太多,無法調(diào)整GC以實現(xiàn)應用程序所需的吞吐量和延遲。 關(guān)于鈴鐺和口哨聲的細節(jié)有很多文檔,但是沒有文檔可以指導您完成這些操作。
權(quán)衡
吞吐量( -XX:GCTimeRatio = 99 ),延遲( -XX:MaxGCPauseMillis = <n> )和內(nèi)存( -Xmx <n> )是收集器所依賴的關(guān)鍵變量。 重要的是要注意,熱點通常無法實現(xiàn)上述目標。 如果低延遲應用程序在幾秒鐘內(nèi)無響應,則可能會造成災難。 權(quán)衡取舍
- 為GC算法提供更多內(nèi)存
- 可以通過包含活動集并減小堆大小來減少GC
- 通過管理堆和生成大小以及控制應用程序的對象分配率,可以減少暫停的頻率
- 可以通過同時運行GC來減少大暫停的頻率
對象壽命
GC算法通常經(jīng)過優(yōu)化,期望大多數(shù)對象的生存期很短,而很少有對象生存期很長。 實驗表明,分代垃圾收集器支持的吞吐量要比非分代垃圾收集器好得多,因此可以在服務(wù)器JVM中使用。
世界停止事件
為了使GC發(fā)生,有必要使正在運行的應用程序的所有線程都必須暫停–垃圾收集器通過發(fā)出信號通知線程在到達安全點時停止的方式來暫停它們。 安全點時間是低延遲應用程序中的重要考慮因素,除其他GC標志外,還可以使用?XX:+ PrintGCApplicationStoppedTime標志來找到安全點時間。
當發(fā)生STW事件時,隨著線程從安全點釋放時恢復,系統(tǒng)將承受很大的調(diào)度壓力,因此, 更少的 STW會使應用程序更高效。
熱點堆組織
Java堆被劃分為多個區(qū)域,在伊甸園中創(chuàng)建了一個對象,并將其移到幸存者空間,并最終移交給了保有權(quán)。 PermGen用于存儲運行時對象,例如類和靜態(tài)字符串。 收集器利用虛擬空間來滿足吞吐量和延遲目標,并調(diào)整區(qū)域大小以達到目標。
對象分配
TLAB(線程本地分配緩沖區(qū))用于在Java中分配對象,這比使用malloc便宜(在大多數(shù)平臺上需要10條指令)。 次要收集的速率與對象分配的速率成正比。 大型對象( -XX:PretenureSizeThreshold = n )可能必須在Old Gen中分配,但是如果閾值設(shè)置為低于TLAB大小,則將不會在Old gen中創(chuàng)建它們-(請注意)不適用于G1 收集器 。
小型收藏
當Eden變滿時,將進行次要收集,一旦對象變舊,即超過閾值( -XX:MaxTenuringThreshold ),對象就會從eden提升到占位空間 。 在次要收集中,將具有已知GC根的活動的可到達對象復制到幸存者空間。 熱點使用卡片表維護跨代引用。 因此,老一代的規(guī)模也是次要收藏成本的一個因素。 通過將Eden的大小調(diào)整為要提升的對象數(shù),可以提高收集效率。 這些很容易發(fā)生STW,因此在最近時期成問題。
主要收藏
主要藏品收集了老一代,以便可以推廣年輕一代的物品。 收集器跟蹤舊一代的填充閾值,并在超過閾值時開始收集。 為避免升級失敗,您將需要調(diào)整舊版本允許容納升級的填充( -XX:PromotedPadding = <n> )。 使用– Xms和-Xmx標志可以避免堆大小調(diào)整。 老一代的壓縮會導致應用程序可能遇到的最大STW暫停之一,并直接與老一代中的活動對象數(shù)量成比例。 通過調(diào)整幸存者空間的大小和占有閾值,可以更慢地填補保有權(quán)空間,但這又會導致更長的次要收集暫停時間,這是由于幸存者空間之間的復制成本增加。
串行收集器
它是具有最小占用空間( -XX:+ UseSerialGC )的最簡單的收集器,并且對次要和主要收集都使用單個線程。
并聯(lián)收集器
有兩種形式( -XX:+ UseParallelGC )和( -XX:+ UseParallelOld GC ),對于次要集合使用多個線程,對于主要集合使用單個線程-因為Java 7u4對這兩種類型的集合都使用多個線程。 Parallel Old在多處理器系統(tǒng)上的性能非常好,適用于批處理應用程序。 提供更多內(nèi)存,更大但更少的收集暫停可以幫助此收集器。 根據(jù)您的應用程序可以承受的暫停時間,在Parallel Old和Concurrent收集器之間權(quán)衡一下(在壓縮舊一代后,現(xiàn)代硬件上每GB實時數(shù)據(jù)的暫停時間應為1到5秒)。
并發(fā)標記掃描(CMS)收集器
CMS( -XX:+ UseConcMarkSweepGC )收集器在舊版本中運行,以收集在大型收集期間不再可訪問的權(quán)屬對象。 CMS不是壓縮的收集器,隨著時間的推移會導致Old gen的碎片化。 當較大的對象無法放入Old gen時,升級失敗將觸發(fā)FullGC。 CMS與您的應用程序一起運行會占用CPU時間。 如果CMS無法以足夠的速度跟上升級的速度,則可能會遭受“并發(fā)模式故障”。
垃圾優(yōu)先(G1)收集器
G1( -XX:+ UseG1GC )是Java 6中引入的新收集器,現(xiàn)已在Java 7中得到正式支持。它是具有部分并發(fā)收集算法的分代收集器,它以較小的STW增量暫停來壓縮Old gen。 它將堆劃分為可變大小的固定大小區(qū)域。 G1是由延遲驅(qū)動的目標驅(qū)動器( –XX:MaxGCPauseMillis = <n> ,默認值= 200ms)。 在龐大的地區(qū)收集物品可能會非常昂貴。 它使用“記憶集”來跟蹤對其他區(qū)域?qū)ο蟮囊谩?記賬和維護“記憶套”涉及很多成本。 與CMS類似,G1可能會發(fā)生疏散失敗(空間溢出)。
替代并行收集器
Oracle JRockit Real Time,IBM Websphere Real Time和Azul Zing是替代的并發(fā)收集器。 根據(jù)作者的說法,Zing是唯一在收集,壓縮之間保持平衡的Java收集器,并為所有世代??保持高吞吐量。 無論堆大小如何,在所有階段(包括次要回收期間),Zing都是并行的。 對于所有針對延遲的并發(fā)收集器,您必須放棄吞吐量并增加占用空間。 堆大小的預算至少為有效設(shè)置的活動集的2到3倍。
垃圾收集監(jiān)控和調(diào)整
始終啟用以收集最佳GC詳細信息的重要標志:
-verbose:gc -Xloggc:<filename> -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime使用Chewiebug , JVisualVM之類的應用程序(帶有Visual GC插件)來研究由于GC動作導致的應用程序行為。 運行可以重復執(zhí)行的代表性負載測試(隨著您了解各種收集器),繼續(xù)嘗試不同的配置,直到達到吞吐量和延遲目標。 jHiccup幫助跟蹤JVM中的暫停。 我們都知道,要在等待時間要求,高對象分配和提升率之間取得平衡,這是一個艱巨的挑戰(zhàn),有時選擇商業(yè)解決方案來實現(xiàn)這一目標可能是一個更明智的想法。
結(jié)論: GC本身就是一個很大的主題,它包含許多組件,其中一些組件不斷被替換,因此重要的是要知道每個組件代表什么。 GC標志與其相關(guān)的組件同樣重要,并且了解它們以及如何使用它們也很重要。 啟用某些標準GC標志來記錄GC日志不會對JVM的性能產(chǎn)生任何重大影響。 只要您遵循作者的方法,就可以使用第三方免費軟件或商業(yè)工具。
—多次閱讀該文章,因為Martin涵蓋了許多有關(guān)GC和收集器的細節(jié),需要仔細檢查并充分理解。 -
馬丁·湯普森(Martin Thompson):神話般的現(xiàn)代硬件獲得“機械同情”
他將神話分為三類- 可能的 , 合理的和失敗的 ! 為了充分利用您擁有的硬件,您需要了解硬件。 進行權(quán)衡,改變旋鈕,這并不像您想的那樣可怕。
好問題:普通開發(fā)人員是否了解他們編程的硬件? 還是不知道發(fā)生了什么事? 還是我們有紀律并努力了解我們使用的平臺?
神話1
CPU并沒有變得越來越快–時鐘速度并不是決定性因素,Sandy Bridge體系結(jié)構(gòu)才是更快的品種。 6個端口支持并行性(6個操作/周期)。 Haswell有8個端口! 代碼除法運算的執(zhí)行速度比任何其他算術(shù)運算都要慢。 CPU具有前端和后端周期。 隨著我們更快地喂食它們,它變得越來越快– 可能
神話2
內(nèi)存為我們提供了隨機訪問權(quán)限 -CPU寄存器和緩沖區(qū),內(nèi)部緩存(L1,L2,L3)和內(nèi)存-分別以對這些區(qū)域的訪問速度增加的順序提到。 CPU一直在通過執(zhí)行直接訪問操作來降低其運行溫度。 寫比讀少麻煩–緩沖區(qū)丟失代價高昂。 L1被組織成包含處理器將執(zhí)行的代碼的高速緩存行–通過沒有高速緩存行未命中來提高效率。 預取程序有助于減少延遲,并有助于讀取流和可預測的數(shù)據(jù)。 TLB丟失也可以提高成本效益(4K =內(nèi)存頁面大小)。 簡而言之,由于底層硬件的工作方式,讀取內(nèi)存并非接近隨機讀取,而是逐次讀取。 編寫高度分支的代碼可能會導致程序執(zhí)行速度變慢–將具有凝聚力的內(nèi)容放在一起是提高效率的關(guān)鍵。 – 破產(chǎn)
注意: TLAB和TLB是兩個不同的概念!
神話3
HDD提供了隨機訪問權(quán)限–旋轉(zhuǎn)的磁盤和一條手臂在讀取數(shù)據(jù)。 與內(nèi)部軌道相比,在外部軌道中放置的扇區(qū)更多(區(qū)域位記錄)。 更快地旋轉(zhuǎn)光盤并不是提高HDD性能的方法。 最小讀寫量為4K。 最佳光盤中的搜索時間為3-6毫秒,筆記本電腦驅(qū)動器的速度較慢(15毫秒)。 旋轉(zhuǎn)延遲需要一些時間。 數(shù)據(jù)傳輸需要100-220 MB /秒。 添加緩存可以改善將數(shù)據(jù)寫入磁盤的能力,而不能改善從磁盤讀取數(shù)據(jù)的速度。 – 破產(chǎn)
神話4
SSD提供隨機訪問–讀寫很棒,工作非常快(一次4K)。 刪除與真正的刪除不同,它被標記為已刪除而不是真正被刪除-因為您無法以高分辨率擦除,因此需要一次擦除整個塊(因此標記為已刪除)。 所有這些都會導致碎片,因此需要進行GC和壓縮。 讀取是平滑的,寫入會受到碎片,GC,壓縮等的阻礙,也要注意寫入放大。 使用SSD時有一些缺點,但總體上還是不錯的。 – 可能
我們能理解所有這些并編寫更好的代碼嗎?
結(jié)論:不要僅僅因為一切都在表面上就把所有東西都視為理所當然,而是在認為可能或合理之前,盡可能自行檢查,檢查和研究內(nèi)部—為了編寫好的代碼并利用這些優(yōu)點特征。
—很好地談?wù)摵秃芎玫貓蟮懒藱C械同情主題,請觀看視頻以獲取針對上述每個硬件組件收集的性能統(tǒng)計信息—
Martin Thompson的
我們使用諸如“如何使用探查器?”之類的東西。 或“如何使用調(diào)試器?”
什么是性能? 可能意味著兩件事,例如吞吐量或帶寬(可以通過多少)和延遲(系統(tǒng)響應的速度)。
響應時間隨我們在系統(tǒng)上施加更多負載而變化。 在設(shè)計任何系統(tǒng)之前,我們需要性能要求,即系統(tǒng)的吞吐量是多少或希望系統(tǒng)響應的速度(延遲)如何? 您的系統(tǒng)是否可以隨著業(yè)務(wù)進行經(jīng)濟擴展?
開發(fā)人員時間昂貴,硬件價格便宜! 對于任何事情,您都需要一個交易預算(將系統(tǒng)要經(jīng)歷或要經(jīng)歷的不同組件和流程進行很好的分解)。
我們?nèi)绾芜M行性能測試? 向系統(tǒng)施加負載,看看吞吐量是上升還是下降? 當我們施加負載時,系統(tǒng)的響應時間是多少? 壓力測試不同于負載測試(請參閱負載測試 ), 壓力測試 (請參閱壓力測試 )是發(fā)生故障(系統(tǒng)崩潰)的一個點,理想的系統(tǒng)將以一條平線繼續(xù)。 同樣重要的是,不僅要從一個點執(zhí)行負載測試,而且要同時從多個點執(zhí)行負載測試。 最重要的是,高持續(xù)時間測試非常重要-這會給表面帶來很多異常,例如內(nèi)存泄漏等。
建立測試套件是一個好主意,這是由較小的部分組成的套件。 我們需要知道我們使用的系統(tǒng)的基本構(gòu)建模塊以及可以從中獲得什么。 我們是否知道系統(tǒng)的不同閾值點及其組件可以處理多少? 了解我們使用的算法,知道如何測量它們并相應地使用它非常重要–使用真實數(shù)據(jù)進行反向操作。
我們什么時候應該測試性能?
“過早的優(yōu)化是萬惡之源” – Donald Knuth /托尼·霍爾
優(yōu)化是什么意思? 知道并選擇您的數(shù)據(jù),并圍繞它進行工作以提高性能。 新的開發(fā)實踐:我們需要經(jīng)常進行早期測試!
從性能的角度來看,“首先測試”實踐非常重要,然后逐漸設(shè)計系統(tǒng),因為將來更改可能會花費很多。
紅色–綠色– 調(diào)試 – 配置文件 –重構(gòu),這是一種“測試優(yōu)先”性能方法的新方法,而不是僅使用“紅色-綠色重構(gòu)”方法! 反饋周期更早,更短比將來發(fā)現(xiàn)問題要好。
如果您在Performance空間工作,則使用“像實時”配對工作站一樣,Mac是一個不好的例子-linux機器是一個更好的選擇。
性能測試可能會導致構(gòu)建失敗–并且它會導致CI系統(tǒng)中的構(gòu)建失敗! 微型基準(即卡尺)應該是什么樣? 在代碼中進行分割可能會非常昂貴,請使用mask運算符 !
并發(fā)測試呢? 僅僅是性能嗎? 不變式? 爭論?
系統(tǒng)性能測試如何? 我們是否應該能夠測試不同范圍的大型和小型客戶。 了解您使用的系統(tǒng)的深入細節(jié)很有趣。 業(yè)務(wù)問題是解決的核心,也是最重要的問題,而不是討論使用什么框架來構(gòu)建它 。 請不要使用Java序列化,因為它不是為在線協(xié)議設(shè)計的! 使用觀察者來衡量系統(tǒng)的性能,而不是從系統(tǒng)內(nèi)部來衡量它。
性能測試課程–很多技術(shù)知識和文化知識。 技術(shù)課–學習如何測量,檢查直方圖! 不要對系統(tǒng)進行采樣,當系統(tǒng)變得奇怪,離群值等等時,我們會漏掉一些東西–直方圖有幫助! 了解系統(tǒng)需要長時間的區(qū)域周圍發(fā)生的事情很重要! 從操作系統(tǒng)捕獲時間也非常重要。
隨著時間的流逝,您將獲得–準確性,精度和分辨率,大多數(shù)人將所有這些混合在一起。 在具有雙插槽的機器上, 時間可能不同步。 時間信息的質(zhì)量在很大程度上取決于您所使用的操作系統(tǒng)。 在虛擬化系統(tǒng)上,或者在兩個不同的機器之間,時間可能是個問題。 這個問題可以解決,就是在兩個系統(tǒng)之間來回操作(注意啟動和停止時鐘時間),然后將它們的一半來獲得更準確的時間。
了解您的系統(tǒng)及其底層組件-獲取指標并進行研究! 使用像perstat這樣的linux工具,將在您的CPU和OS上提供大量與性能和統(tǒng)計相關(guān)的信息-分支預測和緩存丟失!
RDTSC不是命令指令執(zhí)行系統(tǒng),x86是命令指令系統(tǒng),并且操作不會以無序方式發(fā)生。
約束理論! –始終以數(shù)字1開頭,該數(shù)字會花費大部分時間–系統(tǒng)的瓶頸,其余的問題序列可能取決于數(shù)字1,而不是單獨的問題!
嘗試創(chuàng)建績效團隊是一種反模式–讓專家?guī)椭鷮⒓寄軒Ыo團隊的其他成員,并擴展他們的能力!
提防YAGNI –關(guān)于進行性能測試–找借口!
提交構(gòu)建> 3.40分鐘=令人擔憂,對于驗收測試構(gòu)建> 15分鐘=降低團隊信心。
測試環(huán)境應該等于生產(chǎn)環(huán)境! 這些天容易獲得完全相似的硬件!
結(jié)論:在編寫依賴于低延遲的應用程序時,從“測試優(yōu)先”性能測試方法開始。 了解您的目標并朝著目標努力。 從硬件到開發(fā)環(huán)境,全面了解您的底層系統(tǒng)。 在性能測試中,不僅重要的技術(shù)問題,文化的問題也同樣重要。 在團隊中共享和傳播知識,而不是將知識隔離給一兩個人,即所謂的團隊專家。 每個人的責任不只是團隊中的幾個前輩。 了解有關(guān)跨各種硬件和操作系統(tǒng)以及系統(tǒng)之間的時間的更多信息。
由于查看所有此類視頻和文章不切實際,因此在下面的鏈接中提供了許多視頻和文章以供進一步研究。 在許多情況下,我已經(jīng)解釋或直接引用了作者為保留信息和希望傳達的意思而不得不說的話。
有用的資源
- 您的GC日志在對您說話嗎,柯克·佩珀丁(Kirk Pepperdine)的G1GC版– 幻燈片 – 視頻
- 表演特殊興趣小組討論 –由Richard Warburton主持 (視頻)
- 緩存: @RichardWarburto提供的“更有效地理解,衡量和使用CPU緩存” (視頻和幻燈片)
- Jonathan Corbet撰寫的有關(guān)原子I / O操作(Linux)的文章
- Gil Tene的有關(guān)Azul Zing,低延遲GC和OpenJDK的文章和演示 (視頻和幻燈片)
- Martin Thompson的無鎖算法實現(xiàn)終極性能
- Performance Java用戶小組–“面向希望將系統(tǒng)推向新高度的專業(yè)Java開發(fā)人員”
- 通過Kirk Pepperdine 調(diào)整線程池的大小
- Gil Tene 如何不衡量延遲
- 理解Java垃圾收集及其處理方法作者:Gil Tene
- Vanilla #Java了解Core Java的真正工作原理可以幫助您編寫更簡單,更快的應用程序 ,作者Peter Lawrey
- 在生產(chǎn)中對Java進行性能分析 – Kaushik Srenevasan提供
- Alexey Ragozin的HotSpot JVM垃圾回收選項備忘單(v3)
- 優(yōu)化Google的倉庫規(guī)模計算機:NUMA體驗 – Univ的作者。 Cal(SD)和Google的資料!
- MegaPipe:多位作者的可擴展網(wǎng)絡(luò)I / O的新編程接口 !
- 每個程序員應該了解的關(guān)于內(nèi)存的知識Ulrich Drepper
- 內(nèi)存壁壘:針對軟件黑客的硬件視圖 – Paul E. McKenney(Linux技術(shù)中心– IBM Beaverton)
翻譯自: https://www.javacodegeeks.com/2013/12/part-2-of-3-synopsis-of-articles-videos-on-performance-tuning-jvm-gc-in-java-mechanical-sympathy-et-al.html
java jvm調(diào)優(yōu)
總結(jié)
以上是默认站点為你收集整理的java jvm调优_(第2部分,共3部分):有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的摘要...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 马斯克:《华尔街日报》对特斯拉考虑在沙特
- 下一篇: java swing列表数据加监听,【J