Panduan untuk async-profiler

1. Ikhtisar

Java Sampling Profilers biasanya dirancang menggunakan JVM Tool Interface (JVMTI) dan mengumpulkan jejak tumpukan di titik aman. Oleh karena itu, profiler pengambilan sampel ini dapat mengalami masalah bias titik aman.

Untuk tampilan aplikasi yang holistik, kami memerlukan profiler pengambilan sampel yang tidak mengharuskan utas berada di titik aman dan dapat mengumpulkan jejak tumpukan kapan saja untuk menghindari masalah bias titik aman .

Dalam tutorial ini, kita akan menjelajahi async-profiler bersama dengan berbagai teknik pembuatan profil yang ditawarkannya.

2. async-profiler

async-profiler adalah sampling profiler untuk setiap JDK berdasarkan HotSpot JVM. Ini memiliki overhead rendah dan tidak bergantung pada JVMTI.

Ini menghindari masalah bias safepoint dengan menggunakan AsyncGetCallTrace API yang disediakan oleh HotSpot JVM untuk membuat profil jalur kode Java, dan perf_events Linux untuk membuat profil jalur kode asli.

Dengan kata lain, profiler mencocokkan tumpukan panggilan dari kode Java dan jalur kode asli untuk menghasilkan hasil yang akurat.

3. Penyiapan

3.1. Instalasi

Pertama, kami akan mengunduh rilis terbaru async-profiler berdasarkan platform kami. Saat ini, ini hanya mendukung platform Linux dan macOS.

Setelah diunduh, kami dapat memeriksa apakah itu berfungsi di platform kami:

$ ./profiler.sh --version
Async-profiler 1.7.1 built on May 14 2020 Copyright 2016-2020 Andrei Pangin

Sebaiknya periksa semua opsi yang tersedia dengan async-profiler sebelumnya:

$ ./profiler.sh
Usage: ./profiler.sh [action] [options] Actions: start start profiling and return immediately resume resume profiling without resetting collected data stop stop profiling check check if the specified profiling event is available status print profiling status list list profiling events supported by the target JVM collect collect profile for the specified period of time and then stop (default action) Options: -e event profiling event: cpu|alloc|lock|cache-misses etc. -d duration run profiling for seconds -f filename dump output to -i interval sampling interval in nanoseconds -j jstackdepth maximum Java stack depth -b bufsize frame buffer size -t profile different threads separately -s simple class names instead of FQN -g print method signatures -a annotate Java method names -o fmt output format: summary|traces|flat|collapsed|svg|tree|jfr -I include output only stack traces containing the specified pattern -X exclude exclude stack traces with the specified pattern -v, --version display version string --title string SVG title --width px SVG width --height px SVG frame height --minwidth px skip frames smaller than px --reverse generate stack-reversed FlameGraph / Call tree --all-kernel only include kernel-mode events --all-user only include user-mode events --cstack mode how to traverse C stack: fp|lbr|no is a numeric process ID of the target JVM or 'jps' keyword to find running JVM automatically

Banyak dari opsi yang ditampilkan akan berguna di bagian selanjutnya.

3.2. Konfigurasi Kernel

Saat menggunakan async-profiler di platform Linux, kita harus memastikan untuk mengkonfigurasi kernel untuk menangkap tumpukan panggilan menggunakan perf_events oleh semua pengguna:

Pertama, kita akan menyetel perf_event_paranoid ke 1, yang akan memungkinkan profiler mengumpulkan informasi kinerja:

$ sudo sh -c 'echo 1 >/proc/sys/kernel/perf_event_paranoid'

Kemudian, kami akan menyetel kptr_restrict ke 0 untuk menghapus batasan dalam mengekspos alamat kernel:

$ sudo sh -c 'echo 0 >/proc/sys/kernel/kptr_restrict'

Namun, async-profiler akan bekerja dengan sendirinya di platform macOS.

Sekarang platform kita sudah siap, kita dapat membangun aplikasi profil kita dan menjalankannya menggunakan perintah Java:

$ java -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -jar path-to-jar-file

Di sini, kami telah memulai aplikasi pembuatan profil menggunakan flag -XX: + UnlockDiagnosticVMOptions -XX: + DebugNonSafepoints JVM yang sangat direkomendasikan untuk hasil yang akurat .

Sekarang setelah kita siap untuk membuat profil aplikasi kita, mari kita jelajahi berbagai jenis profil yang didukung oleh async-profiler .

4. Profil CPU

Async-profiler mengumpulkan contoh pelacakan tumpukan metode Java, termasuk kode JVM, kelas asli, dan fungsi kernel, saat membuat profil CPU.

Mari membuat profil aplikasi kita menggunakan PID-nya:

$ ./profiler.sh -e cpu -d 30 -o summary 66959 Started [cpu] profiling --- Execution profile --- Total samples : 28 Frame buffer usage : 0.069%

Di sini, kami telah mendefinisikan acara profil cpu dengan menggunakan opsi -e . Kemudian, kami menggunakan -d pilihan untuk mengumpulkan sampel selama 30 detik.

Last, the -o option is useful to define the output format like summary, HTML, traces, SVG, and tree.

Let's create the HTML output while CPU profiling our application:

$ ./profiler.sh -e cpu -d 30 -f cpu_profile.html 66959

Here, we can see the HTML output allows us to expand, collapse, and search the samples.

Additionally, async-profiler supports flame graphs out-of-the-box.

Let's generate a flame graph by using the .svg file extension for the CPU profile of our application:

$ ./profiler.sh -e cpu -d 30 -f cpu_profile.svg 66959

Here, the resulting flame graph shows Java code paths in green, C++ in yellow, and system code paths in red.

5. Allocation Profiling

Similarly, we can collect samples of memory allocation without using an intrusive technique like bytecode instrumentation.

async-profiler uses the TLAB (Thread Local Allocation Buffer) based sampling technique to collect the samples of the heap allocation above the average size of TLAB.

By using the alloc event, we can enable the profiler to collect heap allocations of our profiling application:

$ ./profiler.sh -e alloc -d 30 -f alloc_profile.svg 66255

Here, we can see the object cloning has allocated a large part of memory, which is otherwise hard to perceive when looking at the code.

6. Wall-Clock Profiling

Also, async-profiler can sample all threads irrespective of their status – like running, sleeping, or blocked – by using the wall-clock profile.

This can prove handy when troubleshooting issues in the application start-up time.

By defining the wall event, we can configure the profiler to collect samples of all threads:

$ ./profiler.sh -e wall -t -d 30 -f wall_clock_profile.svg 66959

Here, we've used the wall-clock profiler in per-thread mode by using the -t option, which is highly recommended when profiling all threads.

Additionally, we can check all profiling events supported by our JVM by using the list option:

$ ./profiler.sh list 66959
Basic events: cpu alloc lock wall itimer Java method calls: ClassName.methodName

7. async-profiler With IntelliJ IDEA

IntelliJ IDEA features integration with async-profiler as a profiling tool for Java.

7.1. Profiler Configurations

We can configure async-profiler in IntelliJ IDEA by selecting the Java Profiler menu option at Settings/Preferences > Build, Execution, Deployment:

Also, for quick usage, we can choose any predefined configuration, like the CPU Profiler and the Allocation Profiler that IntelliJ IDEA offers.

Similarly, we can copy a profiler template and edit the Agent options for specific use cases.

7.2. Profile Application Using IntelliJ IDEA

There are a few ways to analyze our application with a profiler.

For instance, we can select the application and choose Run with option:

Or, we can click on the toolbar and choose the Run with option:

Or, by choosing the Run with Profiler option under the Run menu, then selecting the <profiler configuration name>:

Additionally, we can see the option to Attach Profiler to Process under the Run menu. It opens a dialog that lets us choose the process to attach:

Once our application is profiled, we can analyze the profiling result using the Profiler tool window bar at the bottom of the IDE.

The profiling result of our application will look like:

It shows the thread wise results in different output formats like flame graphs, call trees, and method list.

Sebagai alternatif, kita dapat memilih opsi Profiler di bawah menu View> Tool Windows untuk melihat hasilnya:

8. Kesimpulan

Dalam artikel ini, kami menjelajahi async-profiler , bersama dengan beberapa teknik pembuatan profil.

Pertama, kita telah melihat cara mengkonfigurasi kernel saat menggunakan platform Linux, dan beberapa tanda JVM yang direkomendasikan untuk mulai membuat profil aplikasi kita untuk mendapatkan hasil yang akurat.

Kemudian, kami memeriksa berbagai jenis teknik pembuatan profil seperti CPU, alokasi, dan jam dinding.

Terakhir, kami membuat profil aplikasi dengan async-profiler menggunakan IntelliJ IDEA.