最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中JDK14的新特性之JFR,JMC和JFR事件流(推薦)

 更新時(shí)間:2020年05月12日 09:16:56   作者:flydean  
JFR是一個(gè)基于事件的低開銷的分析引擎,具有高性能的后端,可以以二進(jìn)制格式編寫事件,而JMC是一個(gè)GUI工具,用于檢查JFR創(chuàng)建的數(shù)據(jù)文件。本文給大家介紹Java中JDK14的新特性之JFR,JMC和JFR事件流的相關(guān)知識,感興趣的朋友一起看看吧

簡介

Java Flight Recorder(JFR)是JVM的診斷和性能分析工具。它可以收集有關(guān)JVM以及在其上運(yùn)行的Java應(yīng)用程序的數(shù)據(jù)。JFR是集成到JVM中的,所以JFR對JVM的性能影響非常小,我們可以放心的使用它。

一般來說,在使用默認(rèn)配置的時(shí)候,性能影響要小于1%。

JFR的歷史很久遠(yuǎn)了。早在Oracle2008年收購BEA的時(shí)候就有了。JFR一般和JMC(Java Mission Control)協(xié)同工作。

JFR是一個(gè)基于事件的低開銷的分析引擎,具有高性能的后端,可以以二進(jìn)制格式編寫事件,而JMC是一個(gè)GUI工具,用于檢查JFR創(chuàng)建的數(shù)據(jù)文件。

這些工具最早是在BEA的JRockit JVM中出現(xiàn)的,最后被移植到了Oracle JDK。最開始JFR是商用版本,但是在JDK11的時(shí)候,JFR和JMC完全開源了,這意味著我們在非商用的情況下也可以使用了。

而在今天的JDK 14中,引入了一個(gè)新的JFR特性叫做JFR Event Streaming,我們將在本文中詳細(xì)講解。

先介紹一下JFR和JMC。

JFR

上面我們簡單的介紹了一下JFR。JFR是JVM的調(diào)優(yōu)工具,通過不停的收集JVM和java應(yīng)用程序中的各種事件,從而為后續(xù)的JMC分析提供數(shù)據(jù)。

Event是由三部分組成的:時(shí)間戳,事件名和數(shù)據(jù)。同時(shí)JFR也會(huì)處理三種類型的Event:持續(xù)一段時(shí)間的Event,立刻觸發(fā)的Event和抽樣的Event。

為了保證性能的最新影響,在使用JFR的時(shí)候,請選擇你需要的事件類型。

JFR從JVM中搜集到Event之后,會(huì)將其寫入一個(gè)小的thread-local緩存中,然后刷新到一個(gè)全局的內(nèi)存緩存中,最后將緩存中的數(shù)據(jù)寫到磁盤中去。

或者你可以配置JFR不寫到磁盤中去,但是這樣緩存中只會(huì)保存部分events的信息。這也是為什么會(huì)有JDK14 JEP 349的原因。

開啟JFR有很多種方式,這里我們關(guān)注下面兩種:

1.添加命令行參數(shù)

-XX:StartFlightRecording:<options>

啟動(dòng)命令行參數(shù)的格式如上所述。

JFR可以獲取超過一百種不同類型的元數(shù)據(jù)。如果要我們一個(gè)個(gè)來指定這些元數(shù)據(jù),將會(huì)是一個(gè)非常大的功能。所以JDK已經(jīng)為我們提供了兩個(gè)默認(rèn)的profile:default.jfc and profile.jfc。

其中 default.jfc 是默認(rèn)的記錄等級,對JVM性能影響不大,適合普通的,大部分應(yīng)用程序。而profile.jfc包含了更多的細(xì)節(jié),對性能影響會(huì)更多一些。

如果你不想使用默認(rèn)的兩個(gè)jfc文件,也可以按照你自己的需要來創(chuàng)建。

下面看一個(gè)更加完整的命令行參數(shù):

-XX:StartFlightRecording:disk=true,filename=/tmp/customer.jfr,maxage=5h,settings=profile

上面的命令會(huì)創(chuàng)建一個(gè)最大age是5h的profile信息文件。

1.使用jcmd

命令行添加參數(shù)還是太麻煩了,如果我們想動(dòng)態(tài)添加JFR,則可以使用jcmd命令。

jcmd <pid> JFR.start name=custProfile settings=default
jcmd <pid> JFR.dump filename=custProfile.jfr
jcmd <pid> JFR.stop

上面的命令在一個(gè)運(yùn)行中的JVM中啟動(dòng)了JFR,并將統(tǒng)計(jì)結(jié)果dump到了文件中。

上面的custProfile.jfr是一個(gè)二進(jìn)制文件,為了對其進(jìn)行分析,我們需要和JFR配套的工具JMC。

JMC

JDK Mission Control 是一個(gè)用于對 Java 應(yīng)用程序進(jìn)行管理、監(jiān)視、概要分析和故障排除的工具套件。

在JDK14中,JMC是獨(dú)立于JDK單獨(dú)發(fā)行的。我們可以下載之后進(jìn)行安裝。

我們先啟動(dòng)一個(gè)程序,用于做JFR的測試。

@Slf4j
public class ThreadTest {

  public static void main(String[] args) {
    ExecutorService executorService= Executors.newFixedThreadPool(10);
    Runnable runnable= ()->{
      while(true){
        log.info(Thread.currentThread().getName());
        try {
          Thread.sleep(500);
        } catch (InterruptedException e) {
          log.error(e.getMessage(),e);
        }
      }
    };

    for(int i=0; i<10; i++){
      executorService.submit(runnable);
    }
  }
}

很簡單的一個(gè)程序,啟動(dòng)了10個(gè)線程,我們啟動(dòng)這個(gè)程序。

然后再去看看JMC的界面:

我們可以看到在界面的左邊已經(jīng)可以看到運(yùn)行在本機(jī)的ThreadTest程序了。

點(diǎn)擊MBean服務(wù)器,可以看到該java程序的面板信息,里面包含CPU,堆棧信息。

在下面有7個(gè)tab分別是概覽,MBean瀏覽器,觸發(fā)器,系統(tǒng),內(nèi)存,線程,和診斷命令。

通過下面的tab我們可以獲得更加詳細(xì)的java程序的信息,并且通過觸發(fā)器和診斷命令,我們還可以對目標(biāo)java程序的JVM發(fā)送命令。

JMC非常強(qiáng)大,也有很多功能,具體的細(xì)節(jié)大家可以自己運(yùn)行去體會(huì)。

因?yàn)楸疚闹饕菍FR,下面我們將講解如何在JMC中創(chuàng)建JFR和分析JFR。

創(chuàng)建JFR

上面右側(cè)的MBean服務(wù)器下就是飛行記錄器了,也就是我們的目標(biāo)。

點(diǎn)擊飛行記錄器:

我們就可以開始創(chuàng)建一個(gè)JFR了。

目標(biāo)文件就是JFR的生成地址,名稱可以自己隨便起一個(gè),記錄時(shí)間表示需要記錄多長時(shí)間范圍之內(nèi)的JFR。

點(diǎn)下一步:

這一步可以選擇更加詳細(xì)的JVM參數(shù)。

點(diǎn)下一步:

這里,我們可以選擇需要監(jiān)控的Profile事件選項(xiàng)??梢园凑漳愕男枰M(jìn)行選擇。

最后點(diǎn)完成創(chuàng)建JFR。

分析JFR

上面我們的JFR記錄了1分鐘的Profile,在1分鐘之后,我們可以看到目標(biāo)JFR文件生成了。

生成完JFR之后,JMC會(huì)自動(dòng)打開生成的JFR文件,我們得到一個(gè)大綱視圖。

里面包含java應(yīng)用程序,JVM內(nèi)部,環(huán)境和事件瀏覽器。

事件瀏覽器中列出了我們在1分鐘之內(nèi)監(jiān)控的事件。

JMC瀏覽器不僅可以監(jiān)控本機(jī)的應(yīng)用程序,也可以監(jiān)控遠(yuǎn)程的應(yīng)用程序。由于JMC的連接是通過JMX協(xié)議,所以遠(yuǎn)程java程序需要開啟JMX協(xié)議的支持。

JFR事件

JMC好用是好用,但是要一個(gè)一個(gè)的去監(jiān)聽JFR文件會(huì)很繁瑣。接下來我們來介紹一下怎么采用寫代碼的方式來監(jiān)聽JFR事件。

還是上面的圖,如果我們想通過程序來獲取“Class Loading Statistics"的信息,可以這樣做。

上圖的右側(cè)是具體的信息,我們可以看到主要包含三個(gè)字段:開始時(shí)間,Loaded Class Count和 Unloaded Class Count。

我們的思路就是使用jdk.jfr.consumer.RecordingFile去讀取生成的JFR文件,然后對文件中的數(shù)據(jù)進(jìn)行解析。

相應(yīng)代碼如下:

@Slf4j
public class JFREvent {

  private static Predicate<RecordedEvent> testMaker(String s) {
    return e -> e.getEventType().getName().startsWith(s);
  }

  private static final Map<Predicate<RecordedEvent>,
      Function<RecordedEvent, Map<String, String>>> mappers =
      Map.of(testMaker("jdk.ClassLoadingStatistics"),
          ev -> Map.of("start", ""+ ev.getStartTime(),
              "Loaded Class Count",""+ ev.getLong("loadedClassCount"),
              "Unloaded Class Count", ""+ ev.getLong("unloadedClassCount")
          ));

  @Test
  public void readJFRFile() throws IOException {
    RecordingFile recordingFile = new RecordingFile(Paths.get("/Users/flydean/flight_recording_1401comflydeaneventstreamThreadTest21710.jfr"));
    while (recordingFile.hasMoreEvents()) {
      var event = recordingFile.readEvent();
      if (event != null) {
        var details = convertEvent(event);
        if (details == null) {
          // details為空
        } else {
          // 打印目標(biāo)
          log.info("{}",details);
        }
      }
    }
  }

  public Map<String, String> convertEvent(final RecordedEvent e) {
    for (var ent : mappers.entrySet()) {
      if (ent.getKey().test(e)) {
        return ent.getValue().apply(e);
      }
    }
    return null;
  }
}

注意,在convertEvent方法中,我們將從文件中讀取的Event轉(zhuǎn)換成了map對象。

在構(gòu)建map時(shí),我們先判斷Event的名字是不是我們所需要的jdk.ClassLoadingStatistics,然后將Event中其他的字段進(jìn)行轉(zhuǎn)換。最后輸出。

運(yùn)行結(jié)果:

{start=2020-04-29T02:18:41.770618136Z, Loaded Class Count=2861, Unloaded Class Count=0}
...

可以看到輸出結(jié)果和界面上面是一樣的。

JFR事件流

講了這么多,終于到我們今天要講的內(nèi)容了:JFR事件流。

上面的JFR事件中,我們需要去讀取JFR文件,進(jìn)行分析。但是文件是死的,人是活的,每次分析都需要先生成JFR文件簡直是太復(fù)雜了。是個(gè)程序員都不能容忍。

在JFR事件流中,我們可以監(jiān)聽Event的變化,從而在程序中進(jìn)行相應(yīng)的處理。這樣不需要生成JFR文件也可以監(jiān)聽事件變化。

public static void main(String[] args) throws IOException, ParseException {
    //default or profile 兩個(gè)默認(rèn)的profiling configuration files
    Configuration config = Configuration.getConfiguration("default");
    try (var es = new RecordingStream(config)) {
      es.onEvent("jdk.GarbageCollection", System.out::println);
      es.onEvent("jdk.CPULoad", System.out::println);
      es.onEvent("jdk.JVMInformation", System.out::println);
      es.setMaxAge(Duration.ofSeconds(10));
      es.start();
    }
  }

看看上面的例子。我們通過Configuration.getConfiguration("default")獲取到了默認(rèn)的default配置。

然后通過構(gòu)建了default的RecordingStream。通過onEvent
方法,我們對相應(yīng)的Event進(jìn)行處理。

總結(jié)

本文講解了JFR,JMC和JDK14的最新特性JFR event stream。希望能夠?qū)Υ蠹以诠ぷ髦杏兴鶐椭?/p>

本文的例子https://github.com/ddean2009/learn-java-base-9-to-20

到此這篇關(guān)于Java中JDK14的新特性之JFR,JMC和JFR事件流(推薦)的文章就介紹到這了,更多相關(guān)JDK14新特性JFR,JMC和JFR事件流內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java的Lambda表達(dá)式和Stream流的作用以及示例

    Java的Lambda表達(dá)式和Stream流的作用以及示例

    這篇文章主要介紹了Java的Lambda表達(dá)式和Stream流簡單示例,Lambda允許把函數(shù)作為一個(gè)方法的參數(shù),使用Lambda表達(dá)式可以寫出更簡潔、更靈活的代碼,而其作為一種更緊湊的代碼風(fēng)格,使Java的語言表達(dá)能力得到了提升,需要的朋友可以參考下
    2023-05-05
  • springboot整合redis配置詳細(xì)示例代碼

    springboot整合redis配置詳細(xì)示例代碼

    Redis是一種高性能的鍵值存儲數(shù)據(jù)庫,而Spring Boot是一個(gè)簡化了開發(fā)過程的Java框架,將兩者結(jié)合可以輕松地在Spring Boot項(xiàng)目中使用Redis來實(shí)現(xiàn)數(shù)據(jù)緩存、會(huì)話管理和分布式鎖等功能,這篇文章主要給大家介紹了關(guān)于springboot整合redis配置的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • Java語言實(shí)現(xiàn)簡單FTP軟件 FTP軟件效果圖預(yù)覽之下載功能(2)

    Java語言實(shí)現(xiàn)簡單FTP軟件 FTP軟件效果圖預(yù)覽之下載功能(2)

    這篇文章主要為大家詳細(xì)介紹了Java語言實(shí)現(xiàn)簡單FTP軟件,F(xiàn)TP軟件效果圖預(yù)覽之下載功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Java實(shí)現(xiàn)后端跨域的常見解決方案

    Java實(shí)現(xiàn)后端跨域的常見解決方案

    跨源資源共享(CORS——Cross-Origin Resource Sharing,跨源資源共享,或通俗地譯為跨域資源共享)是一種基于 HTTP 頭的機(jī)制,跨域的解決方案有很多種,前后端都有,本文給大家主要介紹Java實(shí)現(xiàn)后端跨域的常見解決方案,需要的朋友可以參考下
    2024-04-04
  • JavaFX實(shí)現(xiàn)拖拽結(jié)點(diǎn)效果

    JavaFX實(shí)現(xiàn)拖拽結(jié)點(diǎn)效果

    這篇文章主要為大家詳細(xì)介紹了JavaFX實(shí)現(xiàn)拖拽結(jié)點(diǎn)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • java中JSqlParser的使用

    java中JSqlParser的使用

    JSqlParse是一款很精簡的sql解析工具,它可以將常用的sql文本解析成具有層級結(jié)構(gòu)的語法樹,本文主要介紹了java中JSqlParser的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • 不規(guī)范使用ThreadLocal導(dǎo)致bug分析解決

    不規(guī)范使用ThreadLocal導(dǎo)致bug分析解決

    這篇文章主要為大家介紹了不規(guī)范使用ThreadLocal導(dǎo)致bug分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • javaNIO中關(guān)于ByteBuffer的用法

    javaNIO中關(guān)于ByteBuffer的用法

    這篇文章主要介紹了javaNIO中關(guān)于ByteBuffer的用法,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Spring?Boot項(xiàng)目如何使用Maven打包并帶上依賴

    Spring?Boot項(xiàng)目如何使用Maven打包并帶上依賴

    在這篇博客中,介紹如何使用Maven將Spring?Boot項(xiàng)目及其依賴項(xiàng)打包成一個(gè)可執(zhí)行的jar文件。我們將使用Spring?Boot的spring-boot-maven-plugin插件來完成這個(gè)任務(wù),感興趣的朋友跟隨小編一起看看吧
    2023-06-06
  • springboot讀取bootstrap配置及knife4j版本兼容性問題及解決

    springboot讀取bootstrap配置及knife4j版本兼容性問題及解決

    這篇文章主要介紹了springboot讀取bootstrap配置及knife4j版本兼容性問題及解決,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06

最新評論

英山县| 林口县| 天台县| 行唐县| 西和县| 云浮市| 西乌珠穆沁旗| 龙游县| 三门峡市| 延吉市| 临西县| 巴东县| 延庆县| 临城县| 巢湖市| 武鸣县| 疏勒县| 深泽县| 明水县| 静安区| 榆社县| 金华市| 崇阳县| 漳浦县| 庆城县| 中超| 永安市| 黎川县| 当阳市| 遂川县| 济源市| 武川县| 娱乐| 咸宁市| 漳州市| 改则县| 宜阳县| 彰武县| 苍梧县| 敦煌市| 甘洛县|