Memantau Aplikasi Java dengan Perekam Penerbangan

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan memeriksa Java Flight Recorder, konsepnya, perintah asasnya, dan cara menggunakannya.

2. Utiliti Pemantauan Java

Java bukan hanya bahasa pengaturcaraan tetapi ekosistem yang sangat kaya dengan banyak alat. JDK mengandungi program yang memungkinkan kita menyusun program kita sendiri, serta memantau keadaan mereka dan keadaan Mesin Maya Java selama kitaran hidup pelaksanaan program sepenuhnya.

The bin folder pengagihan JDK mengandungi, antara lain, program-program berikut yang boleh digunakan untuk profil dan memantau:

  • Java VisualVM (jvisualvm.exe)
  • JConsole (jconsole.exe)
  • Kawalan Misi Java (jmc.exe)
  • Alat Perintah Diagnostik (jcmd.exe)

Kami mencadangkan untuk meneroka kandungan folder ini untuk mengetahui apa alat yang kami ada. Harap maklum bahawa Java VisualVM merupakan sebahagian daripada pengedaran Oracle dan Open JDK pada masa lalu. Namun, bermula dari Java 9, pengedaran JDK tidak lagi dihantar dengan Java VisualVM . Oleh itu, kita harus memuat turunnya secara berasingan dari laman web projek sumber terbuka VisualVM.

Dalam tutorial ini, kita akan fokus pada Java Flight Recorder. Ini tidak terdapat di antara alat yang disebutkan di atas kerana ia bukan program yang berdiri sendiri. Penggunaannya berkait rapat dengan dua alat di atas - Java Mission Control dan Diagnostic Command Tools.

3. Perakam Penerbangan Java dan Konsep Asasnya

Java Flight Recorder (JFR) adalah alat pemantauan yang mengumpulkan informasi tentang peristiwa dalam Java Virtual Machine (JVM) selama pelaksanaan aplikasi Java . JFR adalah sebahagian daripada pengedaran JDK, dan ia disatukan ke dalam JVM.

JFR direka untuk mempengaruhi prestasi aplikasi yang berjalan sesedikit mungkin .

Untuk menggunakan JFR, kita harus mengaktifkannya. Kami dapat mencapainya dengan dua cara:

  1. semasa memulakan aplikasi Java
  2. menyampaikan arahan diagnostik alat jcmd ketika aplikasi Java sudah berjalan

JFR tidak mempunyai alat mandiri. Kami menggunakan Java Mission Control (JMC), yang berisi plugin yang memungkinkan kami memvisualisasikan data yang dikumpulkan oleh JFR.

Ketiga-tiga komponen ini - JFR , jcmd dan JMC - membentuk rangkaian lengkap untuk mengumpulkan maklumat jangka masa rendah dari program Java yang sedang berjalan. Kami mungkin menganggap maklumat ini sangat berguna semasa mengoptimumkan program kami, atau ketika mendiagnosisnya apabila ada yang tidak kena.

Sekiranya kita mempunyai pelbagai versi Java yang terpasang di komputer kita, penting untuk memastikan bahawa penyusun Java ( javac ), pelancar Java ( java ) dan alat yang disebutkan di atas (JFR, jcmd dan JMC) berasal dari pengedaran Java yang sama . Jika tidak, ada risiko tidak dapat melihat data yang berguna kerana format data JFR dari versi yang berbeza mungkin tidak serasi.

JFR mempunyai dua konsep utama: peristiwa dan aliran data. Mari kita bincangkan secara ringkas.

3.1. Acara

JFR mengumpulkan peristiwa yang berlaku di JVM ketika aplikasi Java dijalankan. Acara ini berkaitan dengan keadaan JVM itu sendiri atau keadaan program. Acara mempunyai nama, cap waktu, dan maklumat tambahan (seperti maklumat utas, timbunan pelaksanaan, dan keadaan timbunan).

Terdapat tiga jenis acara yang dikumpulkan oleh JFR:

  • peristiwa segera dicatat segera setelah ia berlaku
  • acara durasi dicatat jika jangka masa berjaya mencapai ambang yang ditentukan
  • contoh peristiwa digunakan untuk mencuba aktiviti sistem

3.2. Aliran data

Acara yang dikumpulkan oleh JFR mengandungi sejumlah besar data. Atas sebab ini, berdasarkan reka bentuk, JFR cukup pantas untuk tidak menghalang program.

JFR menyimpan data mengenai peristiwa dalam satu fail output, flight.jfr.

Seperti yang kita tahu, operasi disk I / O agak mahal. Oleh itu, JFR menggunakan pelbagai buffer untuk menyimpan data yang dikumpulkan sebelum membuang blok data ke disk. Perkara mungkin menjadi sedikit lebih rumit kerana, pada masa yang sama, program mungkin mempunyai banyak proses pendaftaran dengan pilihan yang berbeza.

Oleh kerana itu, kami mungkin menemui lebih banyak data dalam fail output daripada yang diminta, atau mungkin tidak mengikut urutan kronologi . Kita mungkin tidak menyedari fakta ini jika kita menggunakan JMC, kerana ia menggambarkan peristiwa mengikut urutan kronologi.

Dalam beberapa kes yang jarang berlaku, JFR mungkin gagal memindahkan data (misalnya, apabila terdapat terlalu banyak peristiwa atau dalam keadaan pemadaman elektrik). Sekiranya ini berlaku, JFR cuba memberitahu kami bahawa fail output mungkin kehilangan sebahagian data.

4. Cara Menggunakan Perakam Penerbangan Perakam

JFR adalah ciri eksperimen, oleh itu penggunaannya boleh berubah. Sebenarnya, dalam pengedaran sebelumnya, kita harus mengaktifkan ciri komersial untuk menggunakannya dalam pengeluaran. Namun, bermula dari JDK 11, kami mungkin menggunakannya tanpa mengaktifkan apa-apa. Kami selalu dapat melihat nota pelepasan rasmi Java untuk memeriksa cara menggunakan alat ini.

Untuk JDK 8, untuk dapat mengaktifkan JFR, kita harus memulakan JVM dengan pilihan + UnlockCommercialFeatures dan + FlightRecorder .

Seperti yang telah kami nyatakan di atas, terdapat dua cara untuk mengaktifkan JFR. Apabila kita mengaktifkannya secara serentak dengan memulakan aplikasi, kita melakukannya dari baris arahan. Apabila aplikasi sudah berjalan, kami menggunakan alat perintah diagnostik.

4.1. Garis Perintah

Pertama, kita menyusun fail * .java program ke dalam * .class menggunakan javac compiler java standard .

Setelah penyusunan berjaya, kami mungkin memulakan program dengan pilihan berikut:

java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=duration=200s,filename=flight.jfr path-to-class-file

di mana path-to-class-file adalah titik masuk aplikasi * file class .

This command launches the application and activates the recording, which starts immediately and lasts no more than 200 seconds. Collected data is saved in an output file, flight.jfr. We'll describe the other options in more detail in the next section.

4.2. Diagnostic Command Tool

We can also start registering the events by using the jcmd tool. For example:

jcmd 1234 JFR.start duration=100s filename=flight.jfr

Prior to JDK 11, in order to be able to activate JFR in this way, we should start the application with unlocked commercial features:

java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -cp ./out/ com.baeldung.Main

Once the application is running, we use its process id in order to execute various commands, which take the following format:

jcmd   [parameters]

Here's a complete list of the diagnostic commands:

  • JFR.start – starts a new JFR recording
  • JFR.check – checks running JFR recording(s)
  • JFR.stop – stops a specific JFR recording
  • JFR.dump – copies contents of a JFR recording to file

Each command has a series of parameters. For example, the JFR.start command has the following parameters:

  • name – the name of the recording; it serves to be able to reference this recording later with other commands
  • delay – dimensional parameter for a time delay of recording start, the default value is 0s
  • duration – dimensional parameter for a time interval of the duration of the recording; the default value is 0s, which means unlimited
  • filename – the name of a file that contains the collected data
  • maxage – dimensional parameter for the maximum age of collected data; the default value is 0s, which means unlimited
  • maxsize – the maximum size of buffers for collected data in bytes; the default value is 0, which means no max size

We've already seen an example of the usage of these parameters at the beginning of this section. For the complete list of the parameters, we may always consult the Java Flight Recorded official documentation.

Although JFR is designed to have as little of a footprint as possible on the performance of the JVM and the application, it's better to limit the maximum amount of collected data by setting at least one of the parameters: duration, maxage, or maxsize.

5. Java Flight Recorder in Action

Let's now demonstrate JFR in action by using an example program.

5.1. Example Program

Our program inserts objects into a list until an OutOfMemoryError occurs. Then the program sleeps for one second:

public static void main(String[] args) { List items = new ArrayList(1); try { while (true){ items.add(new Object()); } } catch (OutOfMemoryError e){ System.out.println(e.getMessage()); } assert items.size() > 0; try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(e.getMessage()); } }

Without executing this code, we can spot a potential drawback: the while loop will lead to high CPU and memory usage. Let's use JFR to see these drawbacks and probably find others.

5.2. Start Registering

First, we compile our program by executing the following command from the command line:

javac -d out -sourcepath src/main src/main/com/baeldung/flightrecorder/FlightRecorder.java

At this point, we should find a file FlightRecorder.class in the out/com/baeldung/flightrecorder directory.

Now, we'll start the program with the following options:

java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=duration=200s,filename=flight.jfr -cp ./out/ com.baeldung.flightrecorder.FlightRecorder

5.3. Visualize Data

Now, we feed the file flight.jfr to Java Mission Control, which is part of the JDK distribution. It helps us visualize the data about our events in a nice and intuitive way.

Its main screen shows us the information about how the program was using the CPU during its execution. We see that the CPU was loaded heavily, which is quite expected due to the while loop:

On the left side of the view, we see sections General, Memory, Code, and Threads, among others. Each section contains various tabs with detailed information. For example, tab Hot Methods of section Code contains the statistics of method calls:

In this tab, we can spot another drawback of our example program: method java.util.ArrayList.grow(int) has been called 17 times in order to enlarge the array capacity every time there wasn't enough space for adding an object.

In more realistic programs, we may see a lot of other useful information:

  • statistics about created objects, when they were created and destroyed by the garbage collector
  • a detailed report about the threads' chronology, when they were locked or active
  • which I/O operations the application was executing

6. Conclusion

In this article, we introduced the topic of monitoring and profiling a Java application using Java Flight Recorder. This tool remains an experimental one, so we should consult its official site for more complete and recent information.

Seperti biasa, coretan kod tersedia di repositori Github kami.