자바 프로그램을 추적하는 방법?


25

sysadmin으로서 때때로 오류가 전혀 발생하지 않거나 넌센스 오류 메시지를 생성하는 동안 프로그램이 비정상적으로 작동하는 상황에 직면합니다.

과거에는 자바가 들어 오기 전에 두 가지 대책이있었습니다.

  1. 아무것도 도움이되지 않으면-RTFM ;-)
  2. 1.조차도 도움이되지 않는 경우-시스템 호출을 추적하고 무슨 일이 일어나고 있는지 확인하십시오

나는 보통 strace -fLinux 에서이 작업에 사용 합니다 (다른 OS는 비슷한 추적 도구가 있습니다). 이제 이것은 일반적으로 구식 프로그램에서 잘 작동하지만 Java 프로세스 에서 동일한 작업을 수행하면 추적이 매우 흐려집니다. 실제 작업과 관련이없는 것처럼 보이는 시스템 호출이 너무 많으므로 그러한 덤프를 통해 검색하는 것이 끔찍합니다.

더 좋은 방법이 있습니까 (소스 코드를 사용할 수없는 경우)?

답변:


16

ckhan이 언급했듯이 jstackJVM에서 모든 활성 스레드의 전체 스택 추적을 제공하기 때문에 훌륭합니다. SIGQUIT를 사용하여 JVM의 stderr에서도 동일하게 얻을 수 있습니다.

또 다른 유용한 도구는 jmap프로세스의 PID를 사용하여 JVM 프로세스에서 힙 덤프를 가져올 수 있습니다.

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

이 힙 덤프는 visualvm(이제 jvisualvm이라는 표준 Oracle Java SDK 설치의 일부 임) 와 같은 도구로로드 할 수 있습니다 . 또한 VisualVM은 실행중인 JVM에 연결하여 내부 CPU 사용량, 스레드 수 및 힙 사용량 그래프 표시를 포함하여 JVM에 대한 정보를 표시 할 수 있습니다. 이는 누수를 추적하는 데 유용합니다.

다른 도구 jstat( vmstat 3) 는 숫자 인수 (예 :)를 사용하여 실행하는 경우 vmstat와 같은 기간 동안 JVM에 대한 가비지 콜렉션 통계를 수집 할 수 있습니다 .

마지막으로, Java 에이전트를 사용하여로드시 모든 오브젝트의 모든 메소드에 대한 계측을 푸시 할 수 있습니다. 라이브러리 javassist는이 작업을 매우 쉽게 수행 할 수 있도록 도와줍니다. 따라서 자신의 추적을 추가하는 것이 가능합니다. 어려운 점은 추적 출력을 원할 때만 추적 출력을 얻는 방법을 찾는 것이지, 항상 JVM을 크롤링하는 속도를 늦출 수 있습니다. dtrace이와 같은 방식으로 작동 하는 프로그램 이 있습니다. 나는 그것을 시도했지만 성공하지 못했습니다. 에이전트를 계측하기 전에 JVM 부트 스트랩에 필요한 클래스가로드 된 후 에이전트가 모든 클래스를 계측 할 수 없으며, 해당 클래스에 계측을 추가하기에는 너무 늦습니다.

내 제안 -VisualVM으로 시작하여 JVM에 대한 현재 스레드 및 중요한 통계를 표시 할 수 있기 때문에 알아야 할 사항이 있는지 확인하십시오.


그건 그렇고, 이것은 멋진 질문입니다. 더 많은 사람들이 다른 아이디어로 답변을 추가하기를 바랍니다. 수년간 Java를 사용하는 사람들에게 추적에 대해 물었을 때, 그들은 나에게 공허한 응시를 주었다. 아마도 그들은 strace의 굉장함을 알지 못합니다.
— ash

10

Linux 시스템에서 잘못된 프로그램을 디버깅 할 때도 비슷한 도구를 사용하여 시스템에서 실행중인 JVM을 디버깅 할 수 있습니다.

도구 # 1-jvmtop

와 마찬가지로 jvmtop 을 top사용 하여 시스템에서 실행중인 JVM 내에서 어떤 클래스가 사용 되는지 확인할 수 있습니다 . 설치되면 다음과 같이 호출하십시오.

$ jvmtop.sh

결과는 도구처럼 보이도록 비슷한 스타일로되어 있습니다 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

도구 # 2-jvmmonitor

또 다른 대안은 jvmmonitor 를 사용하는 것 입니다. JVM 모니터는 Java 애플리케이션의 CPU, 스레드 및 메모리 사용량을 모니터하기 위해 Eclipse와 통합 된 Java 프로파일 러입니다. 이를 사용하여 로컬 호스트에서 실행중인 JVM을 자동으로 찾거나 port @ host를 사용하여 원격 JVM에 연결할 수 있습니다.

jvmmonitor의 ss

도구 # 3-visualvm

visualvm 은 아마도 JVM 관련 문제를 디버깅 할 때 도달 할 수있는 "도구"일 것입니다. 기능 세트는 매우 깊으며 내부를 매우 깊이 볼 수 있습니다.

애플리케이션 성능 프로파일 링 또는 메모리 할당 분석 :

visualvm # 2의 ss

스레드 덤프를 가져 와서 표시하십시오.

visualvm # 3의 ss

참고 문헌


4

고려하십시오 jstack. 에 대한 일치 strace는 pstack아니지만 더 많은- 아날로그가 있지만 적어도 스냅 샷의 사진을 제 시간에 제공합니다. 필요한 경우 조잡한 흔적을 얻기 위해 함께 묶을 수 있습니다.

이 SO 기사의 제안도 참조하십시오 : https : //.com/questions/1025681/call-trace-in-java


2

RHEL OpenJDK를 사용하는 경우 (또는 비슷한 점은 Oracle의 JDK가 아님) SystemTap 을 사용할 수 있습니다 .

일부 프로브는 자바 명령 행 옵션을 사용하여 사용할 수 있습니다 -XX:+DTraceMethodProbes, -XX:+DTraceAllocProbes, -XX:+DTraceMonitorProbes. 이러한 프로브를 활성화하면 프로그램 성능에 상당한 영향을 미칩니다.

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);
}

jstack()프로세스의 Java 스택을 가져 오는 데 사용할 수도 있지만 JVM 전에 SystemTap을 시작한 경우에만 작동합니다 .


SystemTap은 모든 메소드 를 추적 합니다 . 또한 메소드의 인수를 얻을 수 없습니다. 다른 옵션은 JVMTI라고하는 JVM 고유의 추적 기능을 사용하는 것입니다. 가장 유명한 JVMTI 구현 중 하나는 BTrace 입니다.


0

코드 변경이나 재배치없이 메소드 입력 및 종료를 추적 할 수있는 JVM 추적 도구 인 Jackplay 를 시도하는 것이 좋습니다 .


실행중인 JVM에 첨부 할 수 없습니다. 그 외에도 흥미로운 도구
— Nils
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.