2009-06-03 23 views
118

Java uygulamam için bir hata ayıklama aracı oluşturmayı düşünüyorum.Java'da bir istisna atmadan bir yığın izini boşaltmanın bir yolu var mı?

Exception.printStackTrace() gibi bir yığın izlemesi almak mümkün olup olmadığını, ancak bir istisna atmadan mümkün olup olmadığını merak ediyorum?

Amacım, verilen herhangi bir yöntemde, arayanın yönteminin kim olduğunu görmek için bir yığın ayırmaktır.

Throwable t = new Throwable(); 
t.printStackTrace(); 

Çerçeveyi erişmek istiyorsanız, t.getStackTrace kullanabilirsiniz() Bir almak için:

+2

Bir kullanmak için daha iyi olacaktır mevcut hata ayıklama aracı. Orada birçoğu var, ve bu zamanı bir şeyleri yeniden yaratmak yerine proje üzerinde çalışarak geçirebilirsiniz. Tabii ki bir hata ayıklayıcı yazmayı seviyorsanız, elbette. –

cevap

69

Ayrıca sadece geçerli iş parçacığı iz istiyorsanız

+4

+ 1'i paylaştığınız için teşekkürler, yığın izini analiz etmek istiyorsa kesinlikle yararlıdır! –

174

Evet, sadece

Thread.dumpStack() 
+18

... Bu, yeni bir Özel Durum oluşturur ve 'printStackTrace()' öğesini çağırır. – erickson

+38

... ama atmıyor. – Rob

+0

Soruyu gerçekten yanıtlayan cevap budur. – bruno

23

Böyle bir yığın izleme alabilirsiniz kullanmak yığın çerçeve dizisi.

Hotspot derleyicisinin işleri optimize etmekle meşgul olması durumunda, bu stacktrace öğesinin bazı kareler eksik olabileceğini unutmayın.

+0

Bu cevabı beğeniyorum çünkü bana çıkışı yönlendirmek için bir fırsat sunuyor. 'T.printStackTrace' 't.printStackTrace (System.out) 'ile değiştirebilirim. –

+2

Bir satırda: 'new Throwable(). PrintStackTrace (System.out); –

+0

Bu kabul edilen yanıt olmalıdır. Bu basit ve düz ileri! – Sam

31

. Hayattadır tüm iş parçacıkları için yığın izleri haritasını elde etmek Thread.getAllStackTraces() denemek (çok, tüm dişler daha olabilir sistemde, Ram'ın önerisi gibi:

Thread.currentThread(). getStackTrace()

arayan bulmak için yapın:

private String getCallingMethodName() { 
    StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4]; 
    return callingFrame.getMethodName(); 
} 

Ve arayanın kim bilmesi gereken yöntem içinde bu yöntemi çağırın. Bununla birlikte, bir uyarı kelimesi: listede çağıran çerçevenin indeksi JVM'ye göre değişebilir! Her şey, iznin oluşturulduğu noktayı vurmadan önce getStackTrace içinde kaç tane çağrı katmanının bulunduğuna bağlıdır. Daha sağlam bir çözüm, iz elde etmek ve getCallingMethodName için çerçeveyi aramak üzere yinelemek, ardından gerçek aramayı bulmak için iki adım daha ileriye gitmek olacaktır.

+1

Sadece kendi başına yeni bir İstisna yarat ve [1] 'i indeks olarak kullan! – Daniel

+2

Bu sorunun başlığı "bir istisna atmadan" yazıyor. Kabul edildi, istisna oluşturmayı öneriyorsunuz ama atmıyorsunuz, ama yine de bu sorunun özünde olmadığını düşünüyorum. –

+0

Elbette öyle. İstisna yaratmak, stacktrace elde etmenin en düşük seviyesidir. Thread.currentThread(). GetStackTrace() 'iniz bile bunu yapar, ama yolum daha hızlı yapar :). – Daniel

0

HPROF Java Profiler

Hatta kodda bunu yapmak gerekmez. Java HPROF'ınızı işleminize ekleyebilir ve herhangi bir noktada Control- \ tuşuna basarak yığın dökümü, çalışan iş parçacıkları vb. Çıktı alabilirsiniz. . . uygulama kodunuzu bozmadan. Bu biraz modası geçmiş, Java 6 GUI jconsole ile birlikte geliyor, ama yine de HPROF'u çok kullanışlı buluyorum.

5

Ayrıca, işlem için bir QUIT sinyali göndererek, çalışan bir Java işleminde Thread.getAllStackTraces() işlemini yürütmek üzere JVM'ye bir sinyal gönderebilirsiniz. Unix/Linux

kullanın: process_id Java programının süreç numarasıdır

kill -QUIT process_id

.

Windows'ta uygulamada Ctrl-Break tuşlarına basabilirsiniz, ancak genellikle bir konsol işlemi çalıştırmıyorsanız bunu görmezsiniz.

jstack [-l] <pid>

Bu seçenekler bir üretim ortamında çalışan uygulamalar için oldukça faydalıdır:

JDK6 Bilgisayarınızda herhangi bir çalışan JDK6 sürecinden yığını görüntüler başka bir seçenek, jstack komutunu tanıtıldı ve kolayca değiştirilemez. Çalışma zamanı kilitlenmelerini veya performans sorunlarını teşhis etmek için özellikle kullanışlıdırlar.

http://java.sun.com/developer/technicalArticles/Programming/Stacktrace/ Thread.dumpStack() aslında bir istisna atar Bildirimi o http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html

11

: Eğer çıktı üretmesi yakalamak gerekiyorsa

new Exception("Stack trace").printStackTrace(); 
+7

Bir istisna oluşturur, ancak atmaz. – MatrixFrog

3

StringWriter sw = new StringWriter(); 
new Throwable("").printStackTrace(new PrintWriter(sw)); 
String stackTrace = sw.toString(); 
1

Java 9 StackWalker ve destekleyici sınıfları tanıtıldı yığını yürümek için. İşte

Javadoc birkaç snippet'leridir:

walk yöntem geçerli iş parçacığı StackFrames sıralı akışı açılır ve sonra StackFrame akışı yürümeye verilen işlevi uygular. Akış, yığın çerçeve öğelerini, yığının en alttaki kareye oluşturulduğu yürütme noktasını temsil eden en üst çerçeveden sırayla raporlar. Yürüyüş yöntemi geri döndüğünde StackFrame akışı kapatılır. Kapalı akışı yeniden kullanmak için bir girişimde bulunulursa, IllegalStateException atılacaktır.

...

  1. geçerli iş parçacığının ilk 10 yığını çerçeveleri anlık için

    List<StackFrame> stack = StackWalker.getInstance().walk(s -> 
    s.limit(10).collect(Collectors.toList())); 
    
İlgili konular