1. Gambaran keseluruhan
Dalam tutorial ini, kita akan membincangkan pelbagai cara untuk menangkap benang aplikasi Java.
Benang benang adalah gambaran keadaan semua utas proses Java . Keadaan setiap utas disajikan dengan jejak timbunan, menunjukkan kandungan tumpukan benang. Benang benang berguna untuk mendiagnosis masalah kerana memaparkan aktiviti utas. Benang benang ditulis dalam teks biasa, jadi kami dapat menyimpan isinya ke dalam fail dan melihatnya kemudian di editor teks .
Pada bahagian seterusnya, kita akan melalui pelbagai alat dan pendekatan untuk menghasilkan pembuangan utas.
2. Menggunakan JDK Utilities
JDK menyediakan beberapa utiliti yang dapat menangkap benang aplikasi Java. Semua utiliti terletak di bawah folder tong sampah di dalam direktori utama JDK . Oleh itu, kami dapat melaksanakan utiliti ini dari baris arahan selagi direktori ini berada di jalan sistem kami.
2.1. jstack
jstack adalah utiliti JDK baris perintah yang dapat kita gunakan untuk menangkap dump thread. Ia mengambil pid proses dan memaparkan longgokan benang dalam konsol. Sebagai alternatif, kita dapat mengarahkan outputnya ke fail.
Mari kita lihat sintaks perintah asas untuk menangkap dump thread menggunakan jstack:
jstack [-F] [-l] [-m]
Semua bendera adalah pilihan. Mari lihat maksudnya:
- -F pilihan memaksa dump benang; berguna untuk digunakan apabila jstack pid tidak bertindak balas (proses digantung)
- -l pilihan mengarahkan utiliti untuk mencari penyegerak yang boleh dimiliki di timbunan dan kunci
- -m pilihan mencetak bingkai timbunan asli (C&C ++) sebagai tambahan kepada bingkai timbunan Java
Mari gunakan pengetahuan ini untuk digunakan dengan menangkap thread thread dan mengalihkan hasilnya ke fail:
jstack 17264 > /tmp/threaddump.txt
Ingatlah bahawa kita boleh mendapatkan pid daripada proses Java dengan menggunakan jps arahan.
2.2. Kawalan Misi Java
Java Mission Control (JMC) adalah alat GUI yang mengumpulkan dan menganalisis data dari aplikasi Java. Setelah kami melancarkan JMC, ia memaparkan senarai proses Java yang berjalan di mesin tempatan. Kita juga dapat berhubung dengan proses Java yang terpencil melalui JMC.
Kita dapat mengklik kanan pada proses tersebut dan mengklik pada pilihan " Mula Merakam Penerbangan ". Selepas ini, tab Threads menunjukkan Thread Dumps:

2.3. jvisualvm
jvisualvm adalah alat dengan antara muka pengguna grafik yang memungkinkan kita memantau, menyelesaikan masalah, dan profil aplikasi Java . GUI ringkas tetapi sangat intuitif dan mudah digunakan.
Salah satu daripada banyak pilihannya membolehkan kita menangkap benang. Sekiranya kita mengklik kanan pada proses Java dan memilih pilihan "Thread Dump" , alat akan membuat thread dump dan membukanya di tab baru:

Sehingga JDK 9, Visual VM tidak termasuk dalam pengedaran JDK Oracle dan Open JDK. Oleh itu, jika kita menggunakan Java 9 atau versi yang lebih baru, kita dapat memperoleh JVisualVM dari laman projek sumber terbuka Visual VM.
2.4. jcmd
jcmd adalah alat yang berfungsi dengan menghantar permintaan perintah ke JVM. Walaupun kuat, ia tidak mengandungi fungsi jauh - kita harus menggunakannya di mesin yang sama dengan proses Java berjalan.
Salah satu perintahnya adalah Thread.print . Kita boleh menggunakannya untuk mendapat tempat pembuangan thread hanya dengan menentukan pid proses:
jcmd 17264 Thread.print
2.5. jconsole
jconsole membolehkan kita memeriksa jejak timbunan setiap utas. Sekiranya kita membuka jconsole dan menyambung ke proses Java yang sedang berjalan, kita dapat menavigasi ke tab Threads dan mencari jejak stack setiap thread :

2.6. Ringkasan
Jadi ternyata, terdapat banyak cara untuk menangkap dump thread menggunakan utiliti JDK. Mari luangkan masa untuk merenungkan masing-masing dan menggariskan kebaikan dan keburukan mereka:
- jstack : menyediakan kaedah terpantas dan termudah untuk menangkap thread thread. Walau bagaimanapun, alternatif yang lebih baik tersedia bermula dengan Java 8
- jmc : alat profil dan diagnostik JDK yang dipertingkatkan. Ini meminimumkan overhead prestasi yang biasanya menjadi masalah dengan alat profil
- jvisualvm : alat profil sumber terbuka dan ringan dengan konsol GUI yang sangat baik
- jcmd : sangat hebat dan disyorkan untuk Java 8 dan yang lebih baru. Alat tunggal yang melayani banyak tujuan - menangkap dump thread ( jstack ), timbunan ( jmap ), sifat sistem dan argumen baris perintah ( jinfo )
- jconsole : mari kita periksa maklumat jejak benang
3. Dari Command Line
Di pelayan aplikasi perusahaan, hanya JRE yang dipasang untuk keselamatan. Oleh itu, kami tidak dapat menggunakan utiliti yang disebutkan di atas kerana mereka adalah sebahagian daripada JDK. Walau bagaimanapun, terdapat pelbagai alternatif baris perintah yang membolehkan kita menangkap pembuangan benang dengan mudah.
3.1. kill -3 Command (Linux / Unix)
Cara termudah untuk menangkap dump thread dalam sistem seperti Unix adalah melalui perintah kill , yang dapat kita gunakan untuk mengirim isyarat ke proses menggunakan panggilan sistem kill () . Dalam kes penggunaan ini, kami akan menghantarnya isyarat -3 .
Dengan menggunakan pid yang sama dari contoh sebelumnya, mari kita lihat bagaimana menggunakan kill untuk menangkap dump thread:
kill -3 17264
This way the signal-receiving Java process will print the thread dump on the standard output.
If we run the Java process with the following combination of tuning flags, then it will also redirect the thread dump to the given file:
-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=~/jvm.log
Now if we send the -3 signal, in addition to the standard output, the dump will be available at ~/jvm.log file.
3.2. Ctrl + Break (Windows)
In Windows operating systems, we can capture a thread dump using the CTRL and Break key combination. To take a thread dump, navigate to the console used to launch the Java application and press CTRL and Break keys together.
It's worth noting that, on some keyboards, the Break key is not available. Therefore, in such cases, a thread dump can be captured using CTRL, SHIFT, and Pause keys together.
Both of these commands print the thread dump to the console.
4. Programmatically Using ThreadMxBean
The last approach we will discuss in the article is using JMX. We'll use ThreadMxBean to capture the thread dump. Let's see it in code:
private static String threadDump(boolean lockedMonitors, boolean lockedSynchronizers) { StringBuffer threadDump = new StringBuffer(System.lineSeparator()); ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); for(ThreadInfo threadInfo : threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) { threadDump.append(threadInfo.toString()); } return threadDump.toString(); }
In the above program, we are performing several steps:
- At first, an empty StringBuffer is initialized to hold the stack information of each thread.
- We then use the ManagementFactory class to get the instance of ThreadMxBean. A ManagementFactory is a factory class for getting managed beans for the Java platform. In addition, a ThreadMxBean is the management interface for the thread system of the JVM.
- Setting lockedMonitors and lockedSynchronizers values to true indicates to capture the ownable synchronizers and all locked monitors in the thread dump.
5. Conclusion
In this article, we've shown multiple ways to capture a thread dump.
At first, we discussed various JDK Utilities and then the command-line alternatives. In the last section, we concluded with the programmatic approach using JMX.
Seperti biasa, kod sumber penuh contoh boleh didapati di GitHub.