Bagaimana cara melacak program java?

25

Sebagai sysadmin saya terkadang menghadapi situasi, di mana sebuah program berperilaku tidak normal, sementara tidak membuat kesalahan sama sekali atau membuat pesan kesalahan yang tidak masuk akal.

Di masa lalu - sebelum java masuk - ada dua tindakan balasan:

  1. Jika tidak ada yang membantu - RTFM ;-)
  2. Jika bahkan 1. tidak membantu - melacak panggilan sistem dan melihat apa yang terjadi

Saya biasanya menggunakan strace -funtuk tugas ini dengan Linux (OS lain memiliki alat jejak yang serupa). Sekarang sementara ini biasanya bekerja dengan baik untuk program kuno, jejak menjadi sangat kabur ketika melakukan hal yang sama pada proses java . Ada begitu banyak panggilan sistem yang tampaknya tidak terkait dengan tindakan nyata, sehingga sangat mengerikan untuk mencari melalui dump seperti itu.

Adakah cara yang lebih baik untuk melakukan itu (jika kode sumber tidak tersedia)?

Nils
sumber

Jawaban:

16

Seperti yang disebutkan ckhan, jstacksangat bagus karena memberikan jejak tumpukan penuh dari semua utas aktif di JVM. Hal yang sama dapat diperoleh pada stderr JVM menggunakan SIGQUIT.

Alat lain yang bermanfaat adalah jmapyang bisa mengambil tumpukan heap dari proses JVM menggunakan PID proses:

jmap -dump:file=/tmp/heap.hprof $PID

Tumpukan tumpukan ini dapat dimuat dalam alat-alat seperti visualvm(yang sekarang merupakan bagian dari standar menginstal Java java Oracle, bernama jvisualvm). Selain itu, VisualVM dapat terhubung ke JVM yang sedang berjalan dan menampilkan informasi tentang JVM, termasuk memperlihatkan grafik penggunaan CPU internal, jumlah utas, dan penggunaan tumpukan - bagus untuk melacak kebocoran.

Alat lain jstat,, dapat mengumpulkan statistik pengumpulan sampah untuk JVM selama periode waktu yang sangat mirip dengan vmstat ketika dijalankan dengan argumen numerik (mis vmstat 3.).

Akhirnya, dimungkinkan untuk menggunakan Agen Java untuk mendorong instrumentasi pada semua metode semua objek pada waktu buka. Perpustakaan javassistdapat membantu membuat ini sangat mudah dilakukan. Jadi, layak untuk menambahkan penelusuran Anda sendiri. Bagian yang sulit dengan itu akan menemukan cara untuk mendapatkan jejak output hanya ketika Anda menginginkannya dan tidak sepanjang waktu, yang kemungkinan akan memperlambat JVM menjadi merangkak. Ada sebuah program bernama dtraceyang bekerja dengan cara seperti ini. Saya sudah mencobanya, tetapi tidak terlalu berhasil. Perhatikan bahwa agen tidak dapat menginstrumentasi semua kelas karena yang diperlukan untuk mem-bootstrap JVM dimuat sebelum agen dapat menginstruksikan, dan kemudian sudah terlambat untuk menambahkan instrumentasi ke kelas-kelas tersebut.

Saran Saya - mulailah dengan VisualVM dan lihat apakah itu memberi tahu Anda apa yang perlu Anda ketahui karena dapat menampilkan utas saat ini dan statistik penting untuk JVM.

Abu
sumber
Omong-omong, ini adalah pertanyaan yang luar biasa; Saya harap lebih banyak orang menambahkan jawaban dengan ide lain. Ketika saya bertanya kepada orang-orang yang bekerja dengan Jawa selama bertahun-tahun tentang penelusuran, mereka memberi saya pandangan kosong. Mungkin mereka tidak tahu kehebatan strace.
ash
10

Dalam hal yang sama sia-sia ketika men-debug program yang telah serba salah pada sistem Linux Anda dapat menggunakan alat serupa untuk men-debug menjalankan JVM di sistem Anda.

Alat # 1 - jvmtop

Mirip dengan top, Anda dapat menggunakan jvmtop untuk melihat kelas apa yang ada dalam JVM yang sedang berjalan di sistem Anda. Setelah diinstal, Anda menjalankannya seperti ini:

$ jvmtop.sh

Outputnya ditata serupa agar terlihat seperti alat top:

 JvmTop 0.8.0 alpha   amd64  8 cpus, Linux 2.6.32-27, load avg 0.12
 http://code.google.com/p/jvmtop

  PID MAIN-CLASS      HPCUR HPMAX NHCUR NHMAX    CPU     GC    VM USERNAME   #T DL
 3370 rapperSimpleApp  165m  455m  109m  176m  0.12%  0.00% S6U37 web        21
11272 ver.resin.Resin [ERROR: Could not attach to VM]
27338 WatchdogManager   11m   28m   23m  130m  0.00%  0.00% S6U37 web        31
19187 m.jvmtop.JvmTop   20m 3544m   13m  130m  0.93%  0.47% S6U37 web        20
16733 artup.Bootstrap  159m  455m  166m  304m  0.12%  0.00% S6U37 web        46

Alat # 2 - jvmmonitor

Alternatif lain adalah menggunakan jvmmonitor . JVM Monitor adalah profiler Java yang terintegrasi dengan Eclipse untuk memantau CPU, utas dan penggunaan memori aplikasi Java. Anda dapat menggunakannya untuk secara otomatis menemukan menjalankan JVM di localhost atau dapat terhubung ke JVM jauh menggunakan port @ host.

ss dari jvmmonitor

Alat # 3 - visualvm

visualvm mungkin adalah "alat" untuk meraih ketika debugging masalah dengan JVM. Set fiturnya cukup dalam dan Anda bisa melihat jeroan.

Kinerja aplikasi profil atau menganalisis alokasi memori:

ss dari visualvm # 2

Ambil dan tampilkan dump thread:

ss dari visualvm # 3

Referensi

slm
sumber
4

Pertimbangkan jstack. Tidak cocok untuk strace, lebih dari pstack-analog, tetapi setidaknya akan memberi Anda foto dari snapshot dalam waktu. Bisa merangkai mereka bersama untuk mendapatkan jejak kasar jika Anda harus.

Lihat juga saran di artikel SO ini: /programming/1025681/call-trace-in-java

ckhan
sumber
2

Jika Anda menggunakan RHEL OpenJDK (atau serupa, intinya adalah bahwa itu bukan JDK Oracle), Anda dapat menggunakan SystemTap untuk itu.

Beberapa probe diaktifkan dengan menggunakan opsi baris perintah java -XX:+DTraceMethodProbes, -XX:+DTraceAllocProbes, -XX:+DTraceMonitorProbes. Perhatikan bahwa mengaktifkan probe ini akan secara signifikan mempengaruhi kinerja program.

Berikut ini contoh Script SystemTap:

#!/usr/bin/stap

probe hotspot.class_loaded {
    printf("%12s [???] %s\n", name, class);
}

probe hotspot.method_entry, 
      hotspot.method_return {
    printf("%12s [%3d] %s.%s\n", name, thread_id, class, method);
}

probe hotspot.thread_start, 
      hotspot.thread_stop {
    printf("%12s [%3d] %s\n", name, id, thread_name);
}

probe hotspot.monitor_contended_enter, 
      hotspot.monitor_contended_exit {
    printf("%12s [%3d] %s\n", name, thread_id, class);
}

Anda juga dapat menggunakan jstack()untuk mendapatkan tumpukan Java dari proses, tetapi itu hanya akan berfungsi jika Anda memulai SystemTap sebelum JVM.


Perhatikan bahwa SystemTap akan melacak setiap metode. Itu juga tidak bisa mendapatkan argumen metode. Pilihan lain adalah menggunakan kemampuan penelusuran JVM sendiri yang disebut JVMTI. Salah satu implementasi JVMTI yang paling terkenal adalah BTrace .

myaut
sumber
0

Anda disarankan untuk mencoba Jackplay , yang merupakan alat penelusuran JVM yang memungkinkan Anda melacak entri metode dan keluar tanpa perubahan kode atau pemindahan.

alfredx
sumber
Anda tidak dapat melampirkannya ke JVM yang sedang berjalan. Terlepas dari itu - alat yang menarik
Nils