recorder_将Java Flight Recorder与OpenJDK 11一起使用
recorder
Java Flight Recorder(JFR)曾經是Oracle JDK的商業附加組件。 由于它最近與Java Mission Control一起開源,因此使用OpenJDK 11的每個人現在都可以免費使用此出色的工具對Java應用程序進行故障排除。 JFR以前是專有解決方案,對于那些依賴OpenJDK早期版本的人來說,它可能鮮為人知。 因此,我認為有必要寫一篇有關在OpenJDK 11中使用JFR的新文章。
1.概述
關于Java Flight Recorder
JFR是一種分析工具,用于從正在運行的Java應用程序中收集診斷信息和分析數據。 它的性能開銷可以忽略不計,通常低于1%。 對于運行時間較短的應用程序,此開銷可能會超出該開銷,因為JFR在啟動時需要一些預熱時間。
使用JFR診斷錯誤的應用程序可能會大大縮短解決時間。 異常從出現的最初就可以看出,隨著它的發展,最終直到導致應用程序崩潰的那一點。 當然,并非所有問題都那么嚴重。 JFR收集有關正在運行的線程,GC周期,鎖,套接字,內存使用量以及更多內容的數據。
Java Flight Recorder開源
正如我在介紹中提到的那樣,該功能曾經是Oracle JDK的專有功能,并且正式地它僅適用于付費的Oracle客戶。 實際上,您可以使用-XX:+UnlockCommercialFeatures -XX:+FlightRecorder標志啟用它,并且早期的JVM不會強制使用許可證密鑰或類似的東西。
Oracle公司的Mark Reinhold希望更快地推動Java的發展,并從某些發布周期為六個月的Linux操作系統中汲取了靈感。 我認為他可能想到過Ubuntu,盡管他沒有提及。 但是,從版本9開始的Java SE確實具有可預測的六個月發布周期。
長話短說,為了縮短發布時間,他們現在在單一代碼庫上工作,這使得Oracle JDK和OpenJDK構建可以互換。 最終, 從Java 11開始,Oracle在開源GPL和商業許可下提供了JDK版本 。 如果您習慣于免費獲取Oracle JDK二進制文件,請下載OpenJDK構建,它們在功能上是相同的。
結果,JFR獲得了開源,并通過單一代碼庫簡化了發布過程,從而使OpenJDK對開發人員更具吸引力。
JFR包裝差異
使用-XX:+UnlockCommercialFeatures選項時,Oracle JDK 11會發出警告,而OpenJDK無法識別此選項并報告錯誤。
Java Mission Control也是開源的
JMC是用于打開JFR產生的生產時間性能和診斷記錄的客戶端工具 。 JMC還提供了其他功能,例如JMX控制臺和堆轉儲分析器。 從7到10的Oracle JDK版本包含JMC,但已將其分離,現在可以單獨下載獲得 。
JMC最近也已經開源 ,這意味著現在使用OpenJDK 11的任何人都可以使用整個工具集(JFR + JMC)。在撰寫本文時,第一個開源JMC版本7尚未發布到GA,但是提供了早期訪問版本。
2.使用飛行記錄器
我一直沒有在生產中連續使用JFR,因為那樣會違反Oracle JDK的許可證。 為了發展,一切都可以根據我的最佳知識來使用。 因此,使用Oracle JDK的人們(沒有支持合同)最終不得不在其開發機器上本地重現性能問題。
好吧,那么,讓我們看一些代碼。 這將是對Java Flight Recorder的基礎知識的簡單演示,我在為給我們一些調試目的方面有些麻煩。
public class OOMEGenerator {static BlockingQueue<byte[]> queue = new LinkedBlockingQueue<>();public static void main(String[] args) {new Thread(new Consumer()).start();new Thread(new Producer()).start();}static class Producer implements Runnable {public void run() {while (true) {queue.offer(new byte[3 * 1024 * 1024]);try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}}}}static class Consumer implements Runnable {public void run() {while (true) {try {queue.take();Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}}}為了展示經典的OOME,我們可以將新對象添加到集合中。 我選擇了這一模式,因為我經常在生產中看到這種特殊模式。 也就是說,有兩個(或更多)組件,其中一些產生新的對象,而某些消耗這些對象。 該問題源于以下事實:組件用來通過其進行通信的內部緩沖區的容量可能不受限制。
當我說可能是無界的時,我的意思是緩沖區大小乘以一個平均對象的大小,它是如此之大,一段時間后,它只是吞噬了所有堆空間。 通常可能要花費數小時,數天或一周的時間,但最終會發生OutOfMemoryError 。
開發人員通常認為在日志中看到OutOfMemoryError肯定反映了編程錯誤和內存泄漏。 有時,堆轉儲分析可以肯定地確認或混淆這一點,但是在某些情況下,它不是黑色還是白色,而您根本無法分辨。 在這些情況下,具有歷史數據的JFR成為資源。
啟用JFR
我們可以從上面的簡短程序中看到一個OutOfMemoryError ,它需要一些時間,但是這將會發生。 借助JFR,我們可以詳細了解GC的時間,CPU使用率以及許多其他方面的時間過程以及錯誤的特征。
% java \-Xmx1024m \-Xlog:gc*=debug:file=gc.log:utctime,uptime,tid,level:filecount=10,filesize=128m \-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump.hprof \-XX:StartFlightRecording=\disk=true, \dumponexit=true, \filename=recording.jfr, \maxsize=1024m,\maxage=1d,\settings=profile \path-to-gc-roots=true \OOMEGenerator Started recording 1. Use jcmd 5469 JFR.dump name=1 to copy recording data to file.Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat nl.wizenoze.storm.OOMEGenerator.main(OOMEGenerator.java:12)22.31s user 3.46s system 24% cpu 1:43.94 total我在生產中使用這些調試設置。 從這種意義上說,這些JVM參數也為我自己提供了一個注釋,當我需要它們時,我會在這里找到它們。
與JFR相關的是突出顯示的部分(第5-11行)。 默認情況下,記錄的最大大小,最長的期限或記錄的數據均不受限制。 我嘗試了各種設置,并應用了maxage和maxsize被證明是有用的。 在早期的JDK版本中,JFR曾經具有更多設置,但是在版本11中它們簡化了它們。
我想提醒您注意dumponexit選項。 在正常情況下,通常在停止捕獲數據時將記錄寫入磁盤。 當JVM終止時,自然會發生這種情況。 但是,根據我的經驗,當終止異常時,例如當堆空間不足時,則記錄的大小可能為零字節。 盡管JFR設置的文檔不是很清楚dumponexit有什么區別,但是我觀察到,應用它對于從有問題的JVM中捕獲數據是有利的。
JFR帶有兩個出廠的配置文件( default和profile ),它們定義了應將哪些事件保留到捕獲的記錄中。 如果未指定設置選項,則使用default配置文件。 在此示例中,我使用了更廣泛的配置文件事件定義,還啟用了跟蹤GC根目錄的路徑。 這些會給運行中的JVM帶來更高的開銷,我不建議在生產環境中使用它們。
按需捕獲記錄
只要有JVM,就會將性能數據寫入磁盤,但是可以在任何給定時間使用JCMD實用程序按需導出記錄。 JFR.check命令返回有關當前正在運行的記錄的詳細信息。
% jcmd PID JFR.check name=1 14647: Recording 1: name=1 maxsize=1.0GB maxage=1d (running)除此之外, JFR.dump允許您導出到目前為止已記錄的所有內容,而不必等待正在運行的JVM終止或停止記錄。
%jcmd 5469 JFR.dump name=1 filename=dump.jfrJCMD實用程序提供了其他故障排除選項 。
分析JFR錄音
如前所述,JMC必須單獨下載。 盡管它只是一個早期訪問版本,但我發現它完全可用,而沒有遇到重大故障。 在JMC 6中,添加了“自動分析結果”屏幕,以幫助工程師更快地診斷問題。 我一直在使用較舊的JMC 5.5版本,發現此版本很有用,并且確實提供了有用的技巧。 它已正確地將OOMEGenerator$Producer標識為正在生成的源或大對象,并且還建議平衡線程之間的分配率。
從內存視圖的角度來看,它是可以的,它提供了堆使用情況的圖表,但是由于某些原因,缺少了對象直方圖列表中的數字。 由于JMC的較舊版本無法打開此錄音,因此我不知道該錄音的樣子。 我認為這可能是一個錯誤。
看到GC暫停時間以及堆大小分配更改也很有用,但是在較早的JMC版本中,這種情況看起來更好。
3.注意事項
- JFR記錄不向后兼容 -由OpenJDK 11產生的記錄不向后兼容,并且較舊的JMC版本(嘗試5.5和6)不會打開它們
- JMC 7仍是一個早期訪問版本 – GA中的功能可能會更改,某些錯誤可能會在此處和那里出現。
- 官方Docker映像中存在一個錯誤 –啟用JFR時阻止JVM啟動
- JMC 7無法分析HPROF文件 -盡管OpenJDK的Wiki聲明它能夠做到這一點
4。結論
Java Flight Recorder(JFR)是一種概要分析工具,用于從正在運行的Java應用程序中收集診斷信息和概要分析數據。 它收集有關正在運行的線程,GC周期,鎖,套接字,內存使用量以及更多內容的數據。 JFR和Java Mission Control(一種用于分析記錄的工具)已經開源,并且不再是Oracle的專有產品。 Oracle的這一舉動使OpenJDK對開發人員更具吸引力。
從11版開始,Java Mission Control尚未與JDK捆綁在一起,但可以單獨下載獲得 。
使用偽應用程序,我們有意生成了OutOfMemoryError ,捕獲了堆轉儲和JFR記錄,并使用JMC分析了后者。
JFR和JMC是OpenJDK開源領域中的新事物,OpenJDK 11在撰寫本文時也很新,因此必須經過一段時間才能使這些工具成熟。
翻譯自: https://www.javacodegeeks.com/2018/12/using-java-flight-recorder-openjdk-11.html
recorder
總結
以上是生活随笔為你收集整理的recorder_将Java Flight Recorder与OpenJDK 11一起使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计师接私单怎么处理(设计师接私单怎么处
- 下一篇: 动易怎么调用所有子栏目()