使用JRockit Mission Control進行效能分析和調優
Mission Control是BEA JRockit JVM自帶的一組以極低的開銷來監控、管理和分析生產環境中的應用程式的工具。它包括三個獨立的應用程式:記憶體洩漏監測器(Memory Leak Detector)、JVM執行時分析器(Runtime Analyzer)和管理控制檯(Management Console)。BEA從JRockit R26版本就開始捆綁這個工具套件,目前最新的版本是3.0。最近我們使用其中的Runtime Analyzer對國內某著名行業解決方案進行性分析和調優。
JRockit Runtime Analyzer(JRA)是一個JVM分析器,是一個隨需應變的“動態記錄器”。它記錄了Java應用程式和JVM在一段預定的時間內的詳細記錄。然後通過JRA應用程式對記錄下來的檔案進行離線分析。所記錄的資料包括對方法的呼叫跟蹤、錯誤的同步、鎖定的分析,還有垃圾收集統計資訊,優化決策以及物件統計資訊和其他重要的應用程式/JVM行為。它的目的是讓JRockit開發人員能夠找到良好的方法來基於現實應用程式優化JVM,對於幫助客戶在生產和開發環境中解決問題十分有用。
2.效能資料分析和調優
在本次專案中,操作|A和操作B的百人併發指令碼執行完成的時間接近兩分鐘,因此我們使用JRA進行了2分鐘(120秒)的記錄。在GC常規資訊中,我們發現在短短兩分鐘時間內,垃圾收集的總數高達365次,而由此造成的暫停時間有42.5秒之多。也就是說35%的執行時間是在做垃圾收集。
因為最大堆尺寸已經設定成1024M,對於32位作業系統上的Java應用已經是足夠大了(在IA32構架下,由於作業系統給每個程式的最大記憶體定址空間為1.8G,因此最大堆尺寸不能超過1.8G),因此堆的大小並不是造成頻繁垃圾收集的原因。那麼在高併發度的場景下,可能的影響因素很可能是Nursery大小。
Nursery 也稱為新代,是指執行分代式垃圾收集器時,在堆中分配 新物件 的可用塊區域。當 Nursery 變滿時,會在新垃圾收集中單獨對其進行垃圾收集。Nursery 大小決定了新收集的頻率和持續時間。較大 Nursery 會降低收集的頻率,但是會稍微增加每個新收集的持續時間。 Nursery 之所以具有價值,是因為 Java 應用程式中的大多數物件都是在新代中夭亡的。與收集整個堆相比,應首選從新空間中收集垃圾,因為該收集過程的開銷更低,而且在觸發收集時,新空間中的大多數物件均已死亡。在新收集過程中,JVM 首先確定 Nursery 中的哪些物件是活動的,此後將它們提升到舊空間,並釋放 Nursery,供分配新的小物件使用。
Nursery的預設預設值是10M/CPU,對於我們Clovertown伺服器來說,只有20M。由於出現頻繁收集的情況,那麼我們推斷是由於Nursery的預設值太低的原因。一方面在高併發使用者的場景下,肯定是有大量的新物件產生,那麼Nursery的空閒空間很容易就被耗盡。因此Nursery發生垃圾收集頻率就會比較高。另一方面更短的垃圾收集間隔會使得新物件在Nursery的存活率提高因為很多新物件可能還沒來得及使用完畢就已經發生垃圾收集。這樣更多的物件會被提升到舊代,使得舊代的物件也會急劇增加,從而使得舊代發生垃圾收集的頻率也增加。
因為JRockit JVM可以使用-Xns:<size>來設定Nursery的尺寸,我們要在保證垃圾回收停頓時間(garbage collection-pause)儘可能短的同時,儘量加大Nursery的尺寸,這在建立了大量的臨時物件時尤其重要。推薦值是最大堆尺寸的10%,因此我們在JRockit的執行時引數上新增了 –Xns100m。再次執行指令碼後,JRA收集的資訊顯示GC暫停時間驟降到15.3s,次數也有所減少,降到296:
Nursery大小
|
20M(預設值)
|
100M
|
GC暫停時間
|
42.5s
|
15.3s
|
垃圾收集的總數
|
365
|
296
|
平均暫停時間
|
116ms
|
52ms
|
此外,我們從方法資訊中可以看到呼叫次數最多耗時間最長的兩個方法分別是jrockit.vm.Locks.monitorEnterSecondStage和com.ABC.StateManager.makeState兩個方法。展開前置任務後發現呼叫這兩個方法最多的方法是com.ABC.SqlQueryAction.query。而jrockit.vm.Locks.monitorEnterSecondStage顯然是JRockit實現鎖機制的特定的API。因此我們懷疑是對資料庫的操作時有資源互斥的現象發現。
考慮到高併發使用者的場景下,對資料庫操作的併發度也很高,因此對資料庫連線的爭用比較激烈。我們察看了一下當時WebLogic JDBC的配置,發現connection pool的大小隻是預設值20,相對來說偏小了,對效能會有一定的影響。因此我們增大connection pool的大小到100。重新執行測試指令碼後發現效能有較大提升。
|
JDBC connection size 20 w/ default nursery
|
JDBC connection size 100 w/ 100M nursery
|
Increase %
|
操作A
|
22.125
|
12.079
|
83%
|
操作B
|
35.195
|
21.773
|
62%
|
在效能調優完成後,我們又進行了功能測試(迴歸測試),以驗證上述改動沒有影響系統的功能性正確。
四、小結
其實利用Mission Control對Java應用進行調優並不難,對吧?希望本次效能分析調優的過程可以給大家一些啟發,今後可以應用到日常工作中。
本文轉自Intel_ISN 51CTO部落格,原文連結:http://blog.51cto.com/intelisn/130730,如需轉載請自行聯絡原作者
相關文章
- 使用VisualVM對JAVA程式進行效能分析及調優LVMJava
- 使用sqld360進行特定SQL調優分析SQL
- oracle 通過statspace 進行效能調優Oracle
- 使用pprof進行效能分析
- 【效能調優】效能測試、分析與調優基礎
- 【譯】Google - 使用 webpack 進行 web 效能優化(三):監控和分析應用GoWeb優化
- 使用shouldComponentUpdate進行效能優化優化
- 查詢前等待事件語句,進行效能分析和優化事件優化
- ORACLE 使用TRACE進行SQL效能分析OracleSQL
- PHP 效能分析(三): 效能調優實戰PHP
- TiDB 效能分析&效能調優&優化實踐大全TiDB優化
- Linux系統效能調優之效能分析Linux
- 對AngularJS進行效能調優的7個建議AngularJS
- 分析從管理員角度對Hadoop進行調優Hadoop
- golang 效能調優分析工具 pprof (上)Golang
- golang 效能調優分析工具 pprof(下)Golang
- mongodb之使用explain和hint效能分析和優化MongoDBAI優化
- 使用 XDebug + Webgrind 進行 PHP 程式效能分析WebPHP
- 使用DBMS_PROFILER進行PL/SQL效能分析SQL
- JVM效能調優,記憶體分析工具JVM記憶體
- iOS效能調優之Analyze靜態分析iOS
- JavaEE程式在Glassfish的效能調優分析Java
- 利用perf進行效能分析
- 使用SQL調整顧問進行語句優化SQL優化
- PHP 效能分析第三篇: 效能調優實戰PHP
- 效能測試知多少---效能分析與調優的原理
- 如何對分散式 NewSQL 資料庫 TiDB 進行效能調優分散式SQL資料庫TiDB
- 使用火焰圖進行Java應用效能分析Java
- Docker中使用Xhprof 對程式碼進行效能分析Docker
- 使用xhprof進行線上PHP效能追蹤及分析PHP
- 使用 Spark 進行微服務的實時效能分析Spark微服務
- Spark 效能調優--資源調優Spark
- Spark 效能調優--Shuffle調優 SortShuffleManagerSpark
- Mission Control Plus Mac(視窗管理工具)Mac
- 使用 ASDK 效能調優 - 提升 iOS 介面的渲染效能iOS
- 效能調優(cpu/IO/JVM記憶體分析)JVM記憶體
- 效能測試之測試分析與調優
- Linux伺服器效能分析與調優Linux伺服器