Red HatビルドのOpenJDKでのJDK Mission Controlのセットアップ

Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ(@chiroito)です。

この記事は、Red Hat Developerのブログ記事、Set up JDK Mission Control with Red Hat Build of OpenJDK | Red Hat Developer の翻訳記事です。


https://developers.redhat.com/sites/default/files/styles/article_feature/public/blog/2019/03/pexels-exploration-flight-launch-87080.jpg?itok=jFJcuxZV

JDK Mission Controlは、Red Hat Software Collections (RHSCL)の最新メンバーとなりました。JDK Mission Controlは、HotSpotのJava仮想マシン(JVM)用の強力なプロファイラで、高度なツール群を備えています。これにより、JDK Flight Recorderが収集した広範なデータを効率的かつ詳細に分析できます。このツール群により、開発者や管理者は、OpenJDK 11を使用して本番稼働環境でローカルで実行されている、またはデプロイされているJavaアプリケーションからデータを収集・分析できます。

この記事では、JDK Mission Controlをセットアップする主な例を紹介します。Linuxでは、JDK Mission ControlはRHSCLの一部であり、Windowsでは、Red Hat Customer PortalOpenJDKのzip配布物の一部として提供されています。 Linuxの場合、この手順ではRed Hat Build of OpenJDK 11がすでにインストールされていることを前提としています。ここでは、RHSCLからソフトウェアをインストールするためのシステムの設定方法を紹介します。これはRed Hat Enterprise Linuxの最新の開発技術を提供するものです。そして、JDK Mission Controlをインストールし、簡単なサンプルアプリケーションを実行します。チュートリアル全体の所要時間は10分以内となっています。

Mission Controlのインストール

Microsoft Windows の場合

Microsoft Windows では、Red Hat カスタマーポータルで入手できる OpenJDK の zip に JDK Mission Control と JDK Flight Recorder が含まれるようになりました。アーカイブを解凍すると、JMC バイナリは bin ディレクトリに格納されます。

Red Hat Enterprise Linux の場合

root ユーザとして subscription-manager ツールを使用して、コマンドラインからソフトウェアリポジトリを追加または削除できます。利用可能なソフトウェアリポジトリを表示するには、--list オプションを使用します。また、RHSCL へのアクセス権があることを確認してください。

$ su -
# subscription-manager repos --list | egrep rhscl

どの種類を使用するか(サーバかワークステーションかなど)によって異なります。以下のコマンドでリポジトリを有効にできます。

# subscription-manager repos --enable  rhel-variant-rhscl-7-rpms

以下のコマンドでJMCをインストールします。

$ yum install rh-jmc

JMCをインストールしました。JMCと入力するか、アプリケーションメニューから起動できます。

私のように、複数のバージョンのJavaを実行していて、コマンドラインからJMCを起動したい場合は、以下のオプションを使用して、OpenJDKのRed Hat BuildへのパスでJMCを起動します。

$ scl enable rh-jmc bash
$ jmc -vm /usr/lib/jvm/java-11-openjdk-11.0.2.7-0.el7_6.i386/bin

リアルタイムモニタリング

JMCでは、JVMのリアルタイムモニタリングを行えます。これを行うには、ファイルメニューから新しい接続を作成し、JVMを選択して、JMXコンソールを起動します。その結果、プロセッサ、メモリ消費量、Javaヒープ使用量、JVM CPU使用量などの概要ページが表示されるはずです。

https://developers.redhat.com/blog/wp-content/uploads/2019/03/JMC-Realtime-monitoring-300x151.jpeg

さて、JMCの設定ができましたので、例題を実行して動作を確認してみましょう。

以下は、いくつかのファイルを読み込む簡単な例です。確かに、考慮していない問題があるかもしれません。以下の例では、2つのファイルがあります。シンプルなHTMLファイルと、約1GBのテキストファイルです。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;


public class TextFileReader {

private File textFilePath = null;


public TextFileReader(String textFilePath) {
    if (textFilePath == null)
        throw new IllegalArgumentException();
    this.textFilePath = new File(textFilePath);
}

public void readFile() throws IOException {
    FileReader fileReader = new FileReader(textFilePath);
    BufferedReader bufferedreader = new BufferedReader(fileReader);
    StringBuffer sb = new StringBuffer();
    String strLine;
    while ((strLine = bufferedreader.readLine()) != null) {
        sb.append(strLine);
        sb.append("\n");
    }
    
    fileReader.close();
    System.out.println(sb.toString());
}

public static void main(String[] args) throws IOException{

    new TextFileReader("index.html").readFile();
    new TextFileReader("test.txt").readFile();

}

}

以下のコマンドを実行して、このサンプルをコンパイルして実行してみましょう。

$ javac TextFileReader.java

$ java -XX:+FlightRecorder -XX:StartFlightRecording=dumponexit=true,filename=filereader.jfr TextFileReader

上記のJavaコマンドでは,パラメータ-XX:StartFlightRecordingで,結果をfilereader.jfrにダンプします.

このファイルをJMCで開いて、結果を見てみましょう。

https://developers.redhat.com/blog/wp-content/uploads/2019/03/screenshot-jmc2-300x161.jpeg

JMCは、実行全体に関する掘り下げた詳細な情報を報告します。例えば、JVM内部では、GCが失速していることを示しています。さらに、メモリがあまりない上に大きなファイルでは、それは問題なので、-XX:InitiatingHeapOccupancyPercentの値を下げるか、さらには、十分なメモリを確保する(例:Xms1024m -Xmx4096m)ことで、問題を解決できます。

また、Red HatのソフトウェアエンジニアであるJie Kang氏によるこちらでは、メソッドのプロファイリングがどのように機能し、元のコードの最適化に役立っているかが紹介されています。

JMCは、メモリリークやデッドロックなど、アプリケーションの動作を理解するのに非常に役立ちます。Red Hat Build of OpenJDK 11で試してみてください。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。