Saya berpikir untuk membuat alat debug untuk aplikasi Java saya.
Saya bertanya-tanya apakah mungkin untuk mendapatkan jejak stack, seperti Exception.printStackTrace()
tetapi tanpa benar-benar melempar pengecualian?
Tujuan saya adalah, dalam metode apa pun, membuang tumpukan untuk melihat siapa pemanggil metode itu.
public static void dumpStack() { new Exception("Stack trace").printStackTrace(); }
stderr
, yang tampaknya merupakan implikasi dari pertanyaan tersebut.Jika Anda ingin jejak hanya untuk utas saat ini (daripada semua utas dalam sistem, seperti saran Ram), lakukan:
Thread.currentThread (). getStackTrace ()
Untuk menemukan penelepon, lakukan:
Dan panggil metode itu dari dalam metode yang perlu tahu siapa peneleponnya. Namun, kata peringatan: indeks frame panggilan dalam daftar dapat bervariasi sesuai dengan JVM! Itu semua tergantung pada berapa banyak lapisan panggilan yang ada di dalam getStackTrace sebelum Anda mencapai titik di mana jejak dihasilkan. Solusi yang lebih kuat adalah dengan mendapatkan jejak, dan beralihlah mencari frame untuk getCallingMethodName, kemudian ambil dua langkah lebih jauh untuk menemukan penelepon yang sebenarnya.
sumber
Anda bisa mendapatkan jejak tumpukan seperti ini:
Jika Anda ingin mengakses frame, Anda bisa menggunakan t.getStackTrace () untuk mendapatkan array stack frames.
Perlu diketahui bahwa stacktrace ini (seperti yang lainnya) mungkin kehilangan beberapa frame jika kompiler hotspot sibuk mengoptimalkan hal-hal.
sumber
t.printStackTrace
dengant.printStackTrace(System.out)
.new Throwable().printStackTrace(System.out);
log.log(Level.SEVERE, "Failed to do something", new Throwable());
Perhatikan bahwa Thread.dumpStack () benar-benar melempar pengecualian:
sumber
Anda juga dapat mengirim sinyal ke JVM untuk mengeksekusi Thread.getAllStackTraces () pada proses Java yang sedang berjalan dengan mengirimkan sinyal QUIT ke proses.
Di Unix / Linux gunakan:
kill -QUIT process_id
, di mana process_id adalah nomor proses dari program Java Anda.Di Windows, Anda dapat menekan Ctrl-Break di aplikasi, meskipun Anda biasanya tidak akan melihat ini kecuali Anda menjalankan proses konsol.
JDK6 memperkenalkan opsi lain, perintah jstack, yang akan menampilkan tumpukan dari proses JDK6 yang sedang berjalan di komputer Anda:
jstack [-l] <pid>
Opsi ini sangat berguna untuk aplikasi yang berjalan di lingkungan produksi dan tidak dapat dimodifikasi dengan mudah. Mereka sangat berguna untuk mendiagnosis kebuntuan runtime atau masalah kinerja.
http://java.sun.com/developer/technicalArticles/Programming/Stacktrace/ http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html
sumber
Jika Anda perlu menangkap keluaran
sumber
Java 9 memperkenalkan
StackWalker
dan mendukung kelas untuk menjalankan stack.Berikut beberapa cuplikan dari Javadoc:
sumber
HPROF Java Profiler
Anda bahkan tidak perlu melakukan ini dalam kode. Anda dapat memasang Java HPROF ke proses Anda dan kapan saja tekan Control- \ to output heap dump, running threads, dll. . . tanpa memperbaiki kode aplikasi Anda. Ini agak ketinggalan jaman, Java 6 hadir dengan GUI jconsole, tapi saya masih menemukan HPROF sangat berguna.
sumber
The jawaban dengan Rob Di Marco adalah jauh terbaik jika Anda senang untuk output ke
stderr
.Jika Anda ingin menangkap ke
String
, dengan baris baru sesuai jejak normal, Anda bisa melakukan ini:sumber