※当サイトの記事には、広告・プロモーションが含まれます。

Java 8(Open JDK 8)でJDK Flight Recorder(JFR)を利用。JDK Mission Control(JMC)で解析してみる

gigazine.net

生活していると必ず目にするのがフォント。インターネット上の文字はもちろん、道路標識やお店の看板、シャツにあしらわれてる文字デザインも同様です。フォントデザインは個人のデザイナーが活躍していることも多い一方で、4万5000人のデザイナーが販売を行うMonotypeの独占状態になっています。そのようなフォントデザインとフォントビジネスの歴史について、海外メディアのThe Hustleがまとめています。

「フォント」のルーツと「フォントビジネス」の歴史とは? - GIGAZINE

The Hustleによると、原初のフォントとは、1440年にドイツの印刷業者であるヨハネス・グーテンベルクが聖書を大量生産するために発明した活版印刷機にさかのぼります。その後数世紀、グーテンベルク活版印刷機を模倣した鋳造製品が生まれるたびに、新しい書体・フォントが誕生していきました。

「フォント」のルーツと「フォントビジネス」の歴史とは? - GIGAZINE

⇧ 日本の「独占禁止法」みたいなのが存在しないんですかね?

それにしても、宗教はお金が潤ってることなんかね...うらやまけしからん...

JDK Flight Recorder(JFR)とは

前回、名前が出てきたけども、改めて「JDK Flight Recorder(JFR)」とは?

JDK Flight Recorder is an event recorder built into the OpenJDK Java virtual machine. It can be thought of as the software equivalent of a Data Flight Recorder (Black Box) in a commercial aircraft. It captures information about the JVM itself, and the application running in the JVM. There is a wide variety of data captured, for example method profiling, allocation profiling and garbage collection related events. 

https://en.wikipedia.org/wiki/JDK_Flight_Recorder

The JDK Flight Recorder was designed to minimize the Observer Effect in the profiled system, and is meant to be always on in production systems. The technology was open sourced in 2018.

https://en.wikipedia.org/wiki/JDK_Flight_Recorder

Analysis and visualization of flight recordings are normally done using JDK Mission Control.

https://en.wikipedia.org/wiki/JDK_Flight_Recorder

⇧ とあって、2018年にOSSOpen Source Software)になってるのだけど、

History

JDK Flight Recorder started out as JRockit Flight Recorder, and was originally used as a means to collect data to be used to improve the JVM itself. After Oracle acquired Sun Microsystems, JRockit Flight Recorder was rebranded Java Flight Recorder. In 2018 Java Flight Recorder was open sourced and released as part of OpenJDK 11. When open sourced it was rebranded JDK Flight Recorder, due to Java trademark issues.

https://en.wikipedia.org/wiki/JDK_Flight_Recorder

⇧ 歴史的な経緯から分かるように、管理していた団体が移り変わっていたせいか、ややこしいのだが、

管理団体 名称 有償・無償 備考
Sun Microsystems JRockit Flight Recorder(JFR) 不明 不明
Oracle Java Flight Recorder(JFR) 有償 Oracle JDKの一部
特に統括なし JDK Flight Recorder(JFR) 無償 Open JDKの一部

⇧ 名称で略称がいずれも「JFR」だから、略称で話されるとどれのことを言っているのか認識齟齬が起きやすい気がするのだけど、有償・無償が分かれるようですと。

JDK Flight Recorder(JFR)」で「管理団体」を「特に統括なし」としたのは、

gihyo.jp

⇧ 上記サイト様にありますように、Open JDKに携わっているのが複数の団体・個人となっていて、それをまとめてるような団体が分からなかったので。

で、「JDK Flight Recorder(JFR)」が、どんな機能を提供しているかというと、

foojay.io

⇧ 上記サイト様の図が分かりやすいと思うのだけど、Javaアプリケーションを稼働させている「Java 仮想マシンJVMJava Virtual Machine )」の情報を収集してくれるということらしい。

最終的に、拡張子が「.jfr」というファイルを生成するということらしい。

JDK Mission Control(JMC)とは?

Oracleが発信している情報だとは思うのだけど、

jdk.java.net

JDK Mission Control (JMC) is an advanced set of tools for managing, monitoring, profiling, and troubleshooting Java applications. JMC enables efficient and detailed data analysis for areas such as code performance, memory, and latency without introducing the performance overhead normally associated with profiling and monitoring tools.

https://jdk.java.net/jmc/8/

Documentation

These core libraries packaged along with JMC can be used for parsing, processing, and doing automated analysis of Java Flight Recorder (JFR) files. These libraries are available on Maven Central enabling automated project builds for developers creating their own parsing and visualization tools for analyzing JFR recordings.

https://jdk.java.net/jmc/8/

javaアプリケーションのパフォーマンスなんかを解析できるツールということらしい。で、解析をする対象のデータが、拡張子が「.jfr」のファイル、つまり、「JDK Flight Recorder(JFR)」で生成されたファイルということらしい。

Oracleが公開している別の資料によると、

Java Mission Controlツール・チェーン

Java プロセス・ブラウザと JMX コンソール
  Javaプロセス・ブラウザを使うと、ローカルならびにリモートで実行しているJavaアプリケーションに接続し、リスト化することができます。

暗号化された通信およびユーザー・アクセスを制限することが設定で可能なので、JMCは完全にセキュアなアクセスを提供します。

Javaプロセス・ブラウザはJava Discovery Protocol(JDP)を使って、ローカルで実行しているJavaプロセスおよびリモート実行しているJavaプロセスを自動的に検知します。

図 1は、単一のJava Mission Controlインスタンスが一つ以上のJavaプロセスを様々な通信チャネルで検知、表示、接続する方法を示しています。

https://www.oracle.com/technetwork/jp/java/javaseproducts/mission-control/java-mission-control-wp-2008279-ja.pdf

Javaプロセスから直接、解析することもできそうな書きっぷりですな。

確かに、Tomcatのようなアプリケーションサーバーなんかで稼働してるJavaアプリケーションは動作し続けているから(障害などが発生しない限り、Javaプロセスは終わらない)、ファイル(拡張子が「.jfr」)を解析するよりは、Javaプロセスを解析したほうがリアルタイムな情報が取得できますものね。

WSL 2(Windows Subsystem for Linux 2)のUbuntuでOpen JDK 8をインストールし、Javaのバージョンを切り替える

自分の環境にインストールされているのが、Open JDK 11なので、Open JDK 8をインストールして切り替えていきたいと思います、巷では、Open JDK 21が公開されてるけども...

どうやら、

qiita.com

qiita.com

confrage.jp

⇧ 利用しているLinuxディストリビューションによって、Javaのバージョンを切り替えられるコマンドが異なるようで、

  • Red Had系
    →alternatives
  • Debian
    →update-alternatives

ってことになるんかね?

「update-alternatives」コマンドのマニュアルの説明を見ると、

manpages.ubuntu.com

説明

       update-alternativesDebian の alternatives システムを構成するシンボリックリンクを生成・
       削除・管理したり、リンクの情報を表示したりするツールである。

https://manpages.ubuntu.com/manpages/trusty/ja/man8/update-alternatives.8.html

⇧ とあるので、バージョンを切り替えられるのはJavaに限らないということのようね。

とりあえず、「WSL 2(Windows Subsystem for Linux 2)」のUbuntuを起動したら、

別のコマンドプロンプトを起動し、SSHログイン。

Open JDK 8をインストールする。

Open JDK 8がインストールできたようです。

バージョンを切り替えてみたのですが、

なのだけど、コンパイラとかのバージョンが切り替わっていない...

とりあえず、一旦、最初の設定に戻そう。

⇧ 戻り切っていないんだが...

なるほど、「update-alternatives」はシェル芸みたいな職人芸が必要になるのもイケていないのだけど、そもそも、元の状態に戻せないってアウトじゃないか...

⇧ Open JDK 8にはあるけど、Open JDK 11で削除されたものがある、つまり、ディレクトリ構造が変わってるのが影響してるんかな?

■ls -la /usr/lib/jvm/java-11-openjdk-amd64/man/man1

$ ls -la /usr/lib/jvm/java-11-openjdk-amd64/man/man1
total 240
drwxr-xr-x 2 root root  4096 Sep 17 14:25 .
drwxr-xr-x 4 root root  4096 Dec 27  2022 ..
-rw-r--r-- 1 root root  5324 Aug 25 07:33 jar.1.gz
-rw-r--r-- 1 root root 12692 Aug 25 07:33 jarsigner.1.gz
-rw-r--r-- 1 root root 25467 Aug 25 07:33 java.1.gz
-rw-r--r-- 1 root root 13998 Aug 25 07:33 javac.1.gz
-rw-r--r-- 1 root root 42655 Aug 25 07:33 javadoc.1.gz
-rw-r--r-- 1 root root  2846 Aug 25 07:33 javap.1.gz
-rw-r--r-- 1 root root  2481 Aug 25 07:33 jcmd.1.gz
-rw-r--r-- 1 root root  2048 Aug 25 07:33 jconsole.1.gz
-rw-r--r-- 1 root root  4528 Aug 25 07:33 jdb.1.gz
-rw-r--r-- 1 root root  3201 Aug 25 07:33 jdeps.1.gz
-rw-r--r-- 1 root root  1972 Aug 25 07:33 jinfo.1.gz
-rw-r--r-- 1 root root  2395 Aug 25 07:33 jjs.1.gz
-rw-r--r-- 1 root root  2469 Aug 25 07:33 jmap.1.gz
-rw-r--r-- 1 root root  3303 Aug 25 07:33 jps.1.gz
-rw-r--r-- 1 root root  2433 Aug 25 07:33 jrunscript.1.gz
-rw-r--r-- 1 root root  2276 Aug 25 07:33 jstack.1.gz
-rw-r--r-- 1 root root  6258 Aug 25 07:33 jstat.1.gz
-rw-r--r-- 1 root root  3277 Aug 25 07:33 jstatd.1.gz
-rw-r--r-- 1 root root 22183 Aug 25 07:33 keytool.1.gz
-rw-r--r-- 1 root root  4325 Aug 25 07:33 pack200.1.gz
-rw-r--r-- 1 root root  4529 Aug 25 07:33 rmic.1.gz
-rw-r--r-- 1 root root  4933 Aug 25 07:33 rmid.1.gz
-rw-r--r-- 1 root root  1793 Aug 25 07:33 rmiregistry.1.gz
-rw-r--r-- 1 root root  1789 Aug 25 07:33 serialver.1.gz
-rw-r--r-- 1 root root  2161 Aug 25 07:33 unpack200.1.gz

■ls -la /usr/lib/jvm/java-8-openjdk-amd64/man/man1

$ ls -la /usr/lib/jvm/java-8-openjdk-amd64/man/man1
total 212
drwxr-xr-x 2 root root  4096 Oct 15 13:22 .
drwxr-xr-x 4 root root  4096 Oct 15 13:22 ..
-rw-r--r-- 1 root root  1813 Jul 25 05:17 appletviewer.1.gz
-rw-r--r-- 1 root root  1841 Jul 25 05:17 extcheck.1.gz
-rw-r--r-- 1 root root  6543 Jul 25 05:17 idlj.1.gz
-rw-r--r-- 1 root root  5324 Jul 25 05:17 jar.1.gz
-rw-r--r-- 1 root root 12700 Jul 25 05:17 jarsigner.1.gz
lrwxrwxrwx 1 root root    28 Jul 25 05:17 java.1.gz -> ../../jre/man/man1/java.1.gz
-rw-r--r-- 1 root root 14002 Jul 25 05:17 javac.1.gz
-rw-r--r-- 1 root root 42658 Jul 25 05:17 javadoc.1.gz
-rw-r--r-- 1 root root  2841 Jul 25 05:17 javah.1.gz
-rw-r--r-- 1 root root  2850 Jul 25 05:17 javap.1.gz
-rw-r--r-- 1 root root  2481 Jul 25 05:17 jcmd.1.gz
-rw-r--r-- 1 root root  2048 Jul 25 05:17 jconsole.1.gz
-rw-r--r-- 1 root root  4531 Jul 25 05:17 jdb.1.gz
-rw-r--r-- 1 root root  3201 Jul 25 05:17 jdeps.1.gz
-rw-r--r-- 1 root root  2502 Jul 25 05:17 jhat.1.gz
-rw-r--r-- 1 root root  1972 Jul 25 05:17 jinfo.1.gz
lrwxrwxrwx 1 root root    27 Jul 25 05:17 jjs.1.gz -> ../../jre/man/man1/jjs.1.gz
-rw-r--r-- 1 root root  2469 Jul 25 05:17 jmap.1.gz
-rw-r--r-- 1 root root  3303 Jul 25 05:17 jps.1.gz
-rw-r--r-- 1 root root  2433 Jul 25 05:17 jrunscript.1.gz
-rw-r--r-- 1 root root  1987 Jul 25 05:17 jsadebugd.1.gz
-rw-r--r-- 1 root root  2276 Jul 25 05:17 jstack.1.gz
-rw-r--r-- 1 root root  6258 Jul 25 05:17 jstat.1.gz
-rw-r--r-- 1 root root  3277 Jul 25 05:17 jstatd.1.gz
lrwxrwxrwx 1 root root    31 Jul 25 05:17 keytool.1.gz -> ../../jre/man/man1/keytool.1.gz
-rw-r--r-- 1 root root  1826 Jul 25 05:17 native2ascii.1.gz
lrwxrwxrwx 1 root root    28 Jul 25 05:17 orbd.1.gz -> ../../jre/man/man1/orbd.1.gz
lrwxrwxrwx 1 root root    31 Jul 25 05:17 pack200.1.gz -> ../../jre/man/man1/pack200.1.gz
lrwxrwxrwx 1 root root    34 Jul 25 05:17 policytool.1.gz -> ../../jre/man/man1/policytool.1.gz
-rw-r--r-- 1 root root  4529 Jul 25 05:17 rmic.1.gz
lrwxrwxrwx 1 root root    28 Jul 25 05:17 rmid.1.gz -> ../../jre/man/man1/rmid.1.gz
lrwxrwxrwx 1 root root    35 Jul 25 05:17 rmiregistry.1.gz -> ../../jre/man/man1/rmiregistry.1.gz
-rw-r--r-- 1 root root  1836 Jul 25 05:17 schemagen.1.gz
-rw-r--r-- 1 root root  1800 Jul 25 05:17 serialver.1.gz
lrwxrwxrwx 1 root root    34 Jul 25 05:17 servertool.1.gz -> ../../jre/man/man1/servertool.1.gz
lrwxrwxrwx 1 root root    33 Jul 25 05:17 tnameserv.1.gz -> ../../jre/man/man1/tnameserv.1.gz
lrwxrwxrwx 1 root root    33 Jul 25 05:17 unpack200.1.gz -> ../../jre/man/man1/unpack200.1.gz
-rw-r--r-- 1 root root  2320 Jul 25 05:17 wsgen.1.gz
-rw-r--r-- 1 root root  2744 Jul 25 05:17 wsimport.1.gz
-rw-r--r-- 1 root root  4204 Jul 25 05:17 xjc.1.gz

⇧ だいぶ、変わってらっしゃる...

まぁ、マニュアル部分なので、影響は大きくないのかもしらんけど、気持ち悪さが残りますな...

ちなみに、

takezoe.hatenablog.com

mike-neck.hatenadiary.com

⇧ 上記サイト様で紹介されているように、

  • jenv
  • sdkman

ってツールで管理するという方法もありますと。

既にインストール済みのJDKをSDKMANで管理できるのか?って疑問があったのだけど、ドキュメントを見た感じでは、

sdkman.io

Install Local Version(s)

Using a snapshot version? Already have a local installation? Setup a local version by specifying the path to the local installation:

$ sdk install groovy 3.0.0-SNAPSHOT /path/to/groovy-3.0.0-SNAPSHOT
$ sdk install java 17-zulu /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home

Note that the local version name (3.0.0-SNAPSHOT and 17-zulu in the examples above) must be a unique name which is not already in the list of available version names.

https://sdkman.io/usage

⇧『Already have a local installation? Setup a local version by specifying the path to the local installation:』ってあるから、おそらく、SDKMAN以外でインストールされているJavaも管理できるってことかと。

というわけで、SDKMANを導入してみます。

sdkman.io

github.com

⇧ SDKMAN自体のインストール方法の正解がいまいち分からんのだけど、curlでダウンロードする感じらしい。

curlと言えば、

japan.zdnet.com

⇧少し前に、脆弱性が話題になってましたな。

で、SDKMANをダウンロードしようとしたら、まさかの、zip、unzipがUbuntuにインストールされていなくてエラーになったので、zip、unzipをインストールする。

改めて、SDKMANのダウンロード。

指示通り、コマンドを実行した後に、バージョンが表示されればOKっぽい。

で、SDKMANに既存のJDKを登録するには、

stackoverflow.com

⇧stackoverflowにあるように、都度、「source ~/.sdkman/bin/sdkman-init.sh」で反映させる必要があるっぽい...う~む、SDKMANも微妙...

⇧ 一応、Open JDK 8に切り替わったっぽい。

Java 8(Open JDK 8)でJDK Flight Recorder(JFR)を使ってみる

Open JDK 8に切り替わったので、「JDK Flight Recorder(JFR)」を利用してみますか。

ts0818.hatenablog.com

⇧ 上記の記事の時の環境を利用します。

 

#!/bin/bash

## ■■■■■■■■■■■■■■■
## ■ 変数定義
## ■■■■■■■■■■■■■■■
jstat_TestJvmOption_tsv="jstat.tsv"
#jvm_start_option_Xmx1024m="-Xmx1024m"
jvm_start_option_Xmx2048m="-Xmx2048m"
jvm_start_option_PrintFlagsFinal="-XX:+PrintFlagsFinal"
interval_millsecond=100
limit_display_result_row_count=20000
datetime_format="%Y/%m/%d %H:%M:%S.%3N"
jvm_java_version="-version"
result_log="result.log"

## ■■■■■■■■■■■■■■■
## ■ ファイル初期化
## ■■■■■■■■■■■■■■■
if [ -e ${jstat_TestJvmOption_tsv} ]; then
  rm ${jstat_TestJvmOption_tsv} && touch ${jstat_TestJvmOption_tsv}
else
  touch ${jstat_TestJvmOption_tsv}
fi

## ■■■■■■■■■■■■■■■
## ■ Java実行
## ■■■■■■■■■■■■■■■
# JVMのバージョンを確認
#execute_java_version=$(java ${jvm_java_version})
java ${jvm_java_version} 2>> ${result_log} &&

# JVM起動時の設定を確認(Xmxの設定のみ表示)
jvm_setting_output=$(java ${jvm_start_option_Xmx2048m} ${jvm_start_option_PrintFlagsFinal} 2>&1 | grep -Ei "MaxHeapSize")
echo "${jvm_setting_output}" >> ${result_log} &&

# TestJvmOptionクラスの実行
class_TestJvmOption="TestJvmOption"
jvm_start_option_flight_recorder="-XX:StartFlightRecording=dumponexit=true,filename="
output_jfr_TestJvmOption=TestJvmOption_flight_recording_$(date +"%Y-%m-%d_%H-%M-%S").jfr

#java ${jvm_start_option_Xmx2048m} ${class_TestJvmOption} $1 >> ${result_log} & 
java ${jvm_start_option_flight_recorder}${output_jfr_TestJvmOption},name=${class_TestJvmOption} ${jvm_start_option_Xmx2048m} ${class_TestJvmOption} $1 >> ${result_log} & 
#jps -lm | grep TestJvmOption | awk '{print $1}' | xargs -I{} jstat -gcutil {} ${interval_millsecond} ${limit_display_result_row_count} | awk -F, '{print strftime(`${datetime_format}`,systime()) $1}' >> ${jstat_TestJvmOption_tsv}
#jps -lm | grep TestJvmOption | awk '{print $1}' | xargs -I{} jstat -gc {} ${interval_millsecond} ${limit_display_result_row_count} | awk -F, '{print strftime("%(${datetime_format})",systime()) $1}' >> ${jstat_TestJvmOption_tsv}
#jps -lm | grep TestJvmOption | awk '{print $1}' | xargs -I{} jstat -gc {} ${interval_millsecond} ${limit_display_result_row_count} | awk -v datetime_format="${datetime_format}" -F, '{print strftime(datetime_format, systime()) $1}' >> ${jstat_TestJvmOption_tsv}

# heap dump fileを取得する
jps | grep TestJvmOption | awk '{print $1}' | xargs -I{} jmap -dump:format=b,file=./TestJvmOption_heapdump.hprof {} &

# jstatコマンドの出力をファイルに追記(ヘッダー行を含む)
#jstat -gc $(jps | grep TestJvmOption | awk '{print $1}') ${interval_millsecond} ${limit_display_result_row_count} |
jps | grep TestJvmOption | awk '{print $1}' | xargs -I{} jstat -gc {} ${interval_millsecond} ${limit_display_result_row_count} | 
awk -v datetime_format="${datetime_format}" 'BEGIN { OFS="\t" } {
  split($1, arr, " ");
  ms = sprintf("%.3f", arr[1] / 1000); # ミリ秒を秒に変換し、小数点以下3桁までの文字列にフォーマット
  cmd = "date +\"" datetime_format "\""; # 日時フォーマットを含むdateコマンドを生成
  cmd | getline formatted_date; # dateコマンドを実行してフォーマットされた日時を取得
  close(cmd);

  # 各列をタブ区切りで結合
  output = formatted_date "." ms;
  for (i = 1; i <= NF; i++) {
    output = output "\t" $i;
  }
  print output;
}' >> ${jstat_TestJvmOption_tsv}

#java ${jvm_start_option_PrintFlagsFinal} ${jvm_start_option_Xmx} TestJvmOption $1 >> result.log &
#while jps | grep -q TestJvmOption; 
#do 
#  jstat -gc $(jps | grep TestJvmOption | awk '{print $1}') 100 20000 >> jstat.log; 
#done

#until jps | grep TestJvmOption
#  do 
#    #echo "start jstat TestJvmOption"
#    jstat -gc $(jps | grep TestJvmOption | awk '{print $1}') 100 20000 >> ${jstat_TestJvmOption_tsv}
#  done

#until jps | grep -q TestJvmOption
#  do 
#    jstat -gc $(jps | grep TestJvmOption | awk '{print $1}') 100 20000 | awk -F, '{print strftime("%Y/%m/%d %H:%M:%S",systime()) $1}' >> ${jstat_TestJvmOption_tsv}
#  done

#until jps | grep -q TestJvmOption
#  do
#    jstat -gc $(jps | grep TestJvmOption | awk '{print $1}') 100 20000 | perl -wn -e '$d = `date "+%Y/%m/%d %H:%M:%S"`; chomp $d; print "$d | $_"' >> ${jstat_TestJvmOption_tsv}
#  done


#jstat -gc $(jps | grep TestJvmOption | awk '{print $1}') 100 20000 | awk -F, '{print strftime("%Y/%m/%d %H:%M:%S",systime()) $1}';

⇧ 保存して、実行します。

⇧ Open JDK 8の場合の「JDK Flight Recorder(JFR)」のJVMオプションがハッキリしなくて、試行錯誤してますが、

⇧ 拡張子が「.jfr」のファイルは出力できたようです。

とりあえず、WinSCPで、ホスト側(Windows 10 Home)にダウンロードしておきます。

JDK Mission Control(JMC)で解析してみる

で、まさかの、Eclipse同梱のOpen JDK 8に「JDK Mission Control(JMC)」がインストールされていないというね...

⇧ Open JDKのバージョン的には、「JDK Mission Control(JMC)」に対応してそうな気もするんだが...

JDK Mission Control is an open source tools suite for the Java virtual machine. The tools help finding problems in, and optimizing, programs running on the JVM in production. JDK Mission Control supports OpenJDK 11 (and above) and Oracle JDK 7u40 (and above).

https://en.wikipedia.org/wiki/JDK_Mission_Control

Wikipediaだと、Open JDK 11からってなってるのが気になるんだが...

GitHubのページを見ると、

github.com

Mission Control is an open source production time profiling and diagnostics tool for Java.

Builds of Mission Control can currently be found in the Oracle JDK on supported platforms and in the Eclipse marketplace.

For more information on Mission Control, see https://www.oracle.com/missioncontrol.

https://github.com/openjdk/jmc

Oracleのサイトを確認してくれとなってますな。

で、リンク先に飛んでみると、

www.oracle.com

Java Flight Recorder and JDK Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis.

Java Flight Recorder is a profiling and event collection framework built into the Oracle JDK.

It allows Java administrators and developers to gather detailed low level information about how the Java Virtual Machine (JVM) and the Java application are behaving.

JDK Mission Control is an advanced set of tools that enables efficient and detailed analysis of the extensive of data collected by Java Flight Recorder.

The tool chain enables developers and administrators to collect and analyze data from Java applications running locally or deployed in production environments.

https://www.oracle.com/java/technologies/jdk-mission-control.html

⇧ う~む...「JDK Mission Control(JMC)」がOpen JDK 8で利用できるかどうか知りたいんだが分からんではないか...相変わらずの不親切さ、流石はOracleさん。

jdk.java.net

JMC 8.3.1 General-Availability Release

JDK Mission Control (JMC) is an advanced set of tools for managing, monitoring, profiling, and troubleshooting Java applications. JMC enables efficient and detailed data analysis for areas such as code performance, memory, and latency without introducing the performance overhead normally associated with profiling and monitoring tools.

JDK Mission Control version 8.3.1 (JMC 8) is now available for download. JMC 8 delivers a new dependency view, heatmap view, websocket server to access JFR Stack Trace, flame graph view, enhanced Rules API along with other improvements to functionality and usability. JMC 8 supersedes JMC 7, all JMC 7 users and any remaining JMC 5 users should upgrade to this new version. JMC 8 is now able to analyze recordings from JDK 7 and above. For further details refer to JMC 8 OpenJDK Project Page

https://jdk.java.net/jmc/8/

⇧ とあるのだけど、ここで言っているJDKが、

のどっちのことを言っているのかが分からんのよね...

Wikipediaによると、

OpenJDK (Open Java Development Kit) は、プログラミング言語Javaフリーかつオープンソースの実装である。2006年、サン・マイクロシステムズが始めたもので、GPLリンク例外つきの GNU General Public License (GNU GPL) でライセンスされている。リンク例外つきとしたのは、Javaクラスライブラリのライブラリとしての使用をGPLライセンスの適用外とするためである。OpenJDKはJava SE 7以降の公式リファレンス実装とされている。

OpenJDK - Wikipedia

⇧ Open JDKもバージョン7があるようなのだけど。

とりあえず、

qiita.com

Eclipseプラグインを導入していくことで、「JDK Mission Control(JMC)」を利用できるらしい。

Oracleの「JDK Mission Control(JMC)」の説明のページのリンクからプラグインのリンクがあるのだけど、常に最新版へのリンクになっているっぽい。

2023年10月15日(日)時点だと、「https://download.oracle.com/technology/products/missioncontrol/updatesites/openjdk/8.3.1/ide/」となっている。

download.oracle.com

Requirements

  • Requires Eclipse 4.24 or later.
  • Requires any previously installed versions of JMC 4.x, 5.x, 6.x or 7.x to be uninstalled before installing JMC 8.
  • Note that you need to run your Eclipse on a JDK (version 11 or above) installation for all features to work. For more information on this, please see the Run Eclipse on JDK HOWTO.

https://download.oracle.com/technology/products/missioncontrol/updatesites/openjdk/8.3.1/ide/

⇧ なるほど、Open JDK 11以降でないと動かないと。「JDK Flight Recorder(JFR)」がOpen JDK  8で動くから、「JDK Mission Control(JMC)」も同じバージョンで動くと思ってしまうやんけ...

バージョン合わせないと動かなかったりする機能もあるから、紛らわしいっすな...

で、Eclipseプラグインとしてインストールしようとしても、エラーになってインストールできなかったので、zipをダウンロード

ダウンロードできたら、展開。

で、

www.torutk.com

JMC 8 は、JDK 11以降で実行可能なJavaアプリケーションとなっています。実行するマシンに複数のJDKバージョンが存在する場合、JDK 11以降でJMCが実行されるように設定が必要となる場合があります。この場合、JMCのディレクトリにあるjmc.iniにJMCを実行するJDKのパスを追記します。

  --launcher.appendVmargs
+ -vm
+ C:\Program Files\Java\jdk-17\bin
  -vmargs

Java Flight Recorder - ソフトウェアエンジニアリング - Torutk

⇧ とのことらしいので、

-startup
plugins/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.2.500.v20220509-0833
--launcher.appendVmargs
-vm
C:\Eclipse-2023-06\java\11\bin
-vmargs
-XX:+IgnoreUnrecognizedVMOptions
-XX:+UnlockDiagnosticVMOptions
-XX:+DebugNonSafepoints
-XX:FlightRecorderOptions=stackdepth=128
-XX:+FlightRecorder
-XX:StartFlightRecording=name=JMC_Default,maxsize=100m
-Djava.net.preferIPv4Stack=true
-Djdk.attach.allowAttachSelf=true
--add-exports=java.xml/com.sun.org.apache.xerces.internal.parsers=ALL-UNNAMED
--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED
--add-exports=java.management/sun.management=ALL-UNNAMED
--add-exports=java.management/sun.management.counter.perf=ALL-UNNAMED
--add-exports=jdk.management.agent/jdk.internal.agent=ALL-UNNAMED
--add-exports=jdk.attach/sun.tools.attach=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=jdk.attach/sun.tools.attach=ALL-UNNAMED
-Dsun.java.command=JMC
--add-exports=java.desktop/sun.awt.windows=ALL-UNNAMED

⇧ 設定に追記。利用するJDKは、Eclipseに同梱されてるものを指定してますが、Open JDK 11以降であれば大丈夫かと。

で、「jcm.exe」をダブルクリック。

起動できたようです。

そしたらば、

JDK Flight Recorder(JFR)」で生成していた、拡張子が「.jfr」のファイルを開きます。

ファイルが開けたのだけど、

⇧う~む、

  • JDK Flight Recorder(JFR)
  • JDK Mission Control(JMC)

どっちのエラーなのかが分かり辛い...

そして、

⇧ 正常に「JDK Flight Recorder(JFR)」でデータが取れているのかが分からん...

う~む、相変わらず、Javaの仕組みがよく分からん...

毎度モヤモヤ感が半端ない...

今回はこのへんで。