JVM 힙 메모리 덤프를 가져오는 일반적인 방법

1. 힙 메모리 덤프 소개

힙 덤프(Heap Dump)는 특정 시점의 JVM 힙 메모리의 스냅샷을 말하며, 일반적으로 hprof바이너리 파일 형태로 저장된다. 이는 메모리 누수를 분석하고 Java 프로그램의 메모리 사용을 최적화하는 데 사용할 수 있습니다.

일반적인 메모리 덤프 분석 도구에는 jhat , JVisualVM 및 Eclipse 기반 MAT 도구가 포함됩니다.

다음은 힙 메모리 덤프를 얻는 일반적인 방법을 설명합니다.

2. JDK 내장 도구 사용

JDK_HOME/binJDK 에는 디렉토리에 많은 진단 도구가 내장되어 있습니다 . 일반적으로 이 디렉토리는 시스템 PATH 경로에 포함될 수 있으며 명령줄에서 직접 호출할 수 있습니다.
JDK에 내장된 힙 메모리 덤프 도구는 다음과 같습니다.

2.1 jmap도구

jmapJVM 메모리의 통계를 출력하는 데 사용할 수 있으며 로컬 JVM 및 원격 JVM 인스턴스에 대한 액세스를 지원합니다.

-dump힙 메모리 덤프를 가져오려면 옵션을 사용하세요 . 명령은 다음과 같습니다.

jmap -dump:[live],format=b,file=<file-path> <pid>

-dump:옵션 뒤에는 다음 매개변수를 지정할 수 있습니다.

  • live: 선택적 매개변수; 살아남은 객체만 출력됨을 나타냅니다. 즉, 재활용 가능한 부분을 지우기 위해 FullGC가 먼저 실행됩니다.
  • format=b: 덤프 파일을 바이너리 형식으로 지정하는 선택적 매개변수입니다. 힙 메모리를 덤프할 때 기본값은 바이너리 형식입니다.
  • file: 덤프 파일의 저장 경로를 지정합니다.
  • pid: Java 프로세스의 pid를 지정합니다.

사용예는 다음과 같습니다.

jmap -dump:live,format=b,file=/tmp/dump.hprof 12587
# 或者
jmap -dump:file=/tmp/dump.hprof 12587

JVM 프로세스의 pid는 일반적으로 jps명령을 통해 얻습니다. 물론 jcmd명령이나 ps명령을 사용하여 쿼리할 수도 있습니다.

2.2 jcmd도구

jcmd다목적 명령줄 진단 도구로, 작동 원리는 실행될 명령을 특정 JVM 인스턴스로 보내는 것이므로 로컬 시스템에서만 지원됩니다.

명령 중 하나는 GC.heap_dump힙 메모리 덤프를 얻는 데 사용할 수 있으며 pid만 지정하면 되며 명령 형식은 다음과 같습니다.

jcmd <pid> GC.heap_dump <file-path>

예제 사용법도 비슷합니다.

jcmd 12587 GC.heap_dump /tmp/dump.hprof

jmap과 마찬가지로 메모리 덤프 파일은 바이너리입니다.
명령은 실행을 위해 특정 JVM에 매개변수로 전달되므로 파일 경로는 절대 경로인 것이 좋습니다.

2.3 JVisualVM 도구

JVisualVM은 Java 애플리케이션을 모니터링, 분석 및 진단하는 데 사용할 수 있는 그래픽 인터페이스 도구입니다.

img

그래픽 인터페이스는 간단하고 우아하며 강력하며 많은 플러그인을 지원합니다.

기능 중 하나는 힙 메모리 스냅샷을 캡처하고, 프로그램을 열고, 보이는 Java 프로세스를 마우스 오른쪽 버튼으로 클릭한 다음 "Heap Dump"를 선택하여 새 메모리 덤프 파일을 생성하고 탭에서 새로 열린 파일에 자동으로 저장하는 것입니다.

여기에 이미지 설명을 삽입하세요

완료 후 기본정보(Basic Info)에서 덤프파일의 디렉토리 정보를 확인할 수 있습니다.

3. 힙 메모리 덤프를 자동으로 수행합니다.

java.lang.OutOfMemoryError위에 소개된 도구는 모두 수동으로 실행되며 때로는 메모리 오버플로 오류가 발생할 때 JVM이 자동으로 힙 메모리 덤프를 수행하여 이후 조사 및 분석을 용이하게 하기를 바랍니다 . HeapDumpOnOutOfMemoryErrorJVM은 다음 형식으로 명령줄 시작 매개변수를 제공합니다 .

java -XX:+HeapDumpOnOutOfMemoryError

옵션으로 덤프 경로를 지정 하지 않으면 HeapDumpPath자동으로 시작 디렉터리에 저장되며, 파일 이름 형식은 java_pid<pid>.hprof.

지정된 매개변수 HeapDumpPath를 사용하는 예는 다음과 같습니다.

java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<file-or-dir-path>

Java 프로그램을 실행하는 동안 메모리 오버플로가 발생하면 로그에 다음과 같은 내용이 표시됩니다.

java.lang.OutOfMemoryError: Requested array size exceeds VM limit
Dumping heap to java_pid12587.hprof ...
Exception in thread "main" Heap dump file created [4744371 bytes in 0.029 secs]
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    at com.baeldung.heapdump.App.main(App.java:7)

여기에 자동으로 생성된 덤프 파일의 이름은 java_pid12587.hprof.

보시다시피 이 옵션은 매우 유용하며 일반적으로 실행되는 프로그램에 대한 오버헤드가 거의 없습니다. 따라서 특히 프로덕션 환경에서는 이 옵션을 활성화하는 것이 좋습니다.

물론 이 옵션은 HotSpotDiagnosticJMX 클라이언트에서 HeapDumpOnOutOfMemoryError옵션 값을 설정하는 것과 같이 MBean을 통해 동적으로 설정할 수도 있습니다 true.

여기에 이미지 설명을 삽입하세요

MBeans 및 JMX에 대한 자세한 내용은 다음을 참조하세요. JMX 및 관련 도구: 산은 작지만 진실은 분명합니다.

4. JMX 방법

마지막으로 JMX를 통해 힙 메모리 덤프를 얻는 방법을 살펴보겠습니다. 기본적으로 매개변수가 있는 메소드를 HotSpotDiagnostic제공하는 이 MBean을 호출합니다 dumpHeap.

  • outputFile.hprof: 일반적 으로 접미사로 끝나는 덤프 파일의 경로입니다 .
  • live: 로 설정하면 의 사용과 유사하게 true라이브 객체만 덤프됩니다 .jmap

다음은 사용 예입니다.

4.1 JMX 클라이언트 도구

HotSpotDiagnosticMBean을 조작하는 가장 쉬운 방법은 그래픽 인터페이스 클라이언트(예 JConsole: JVisualVM등) 를 사용하는 것입니다.

그것을 열고 JConsole, 지정된 Java 프로세스에 연결하고, MBeans탭 으로 전환하고, com.sun.management.패키지 아래에서 찾아 HotSpotDiagnostic해당 dumpHeap메소드를 실행하십시오.

여기에 이미지 설명을 삽입하세요

그런 다음 p0및 슬롯에 p1해당 매개변수를 입력 outputFile하고 live실행합니다 dumpHeap.

4.2 프로그래밍 방식으로 호출

먼저 MBeanServer인스턴스를 얻은 후 HotSpotDiagnosticMXBean시스템에 등록된 MBean을 얻은 후 dumpHeap메소드를 호출해야 합니다.샘플 코드는 다음과 같습니다.

public static void dumpHeap(String filePath, boolean live) throws IOException {
    
    
    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(
      server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
    mxBean.dumpHeap(filePath, live);
}

hprof파일을 덮어쓸 수 없습니다. 파일이 이미 존재하는 경우 오류가 보고됩니다 .

Exception in thread "main" java.io.IOException: File exists
    at sun.management.HotSpotDiagnostic.dumpHeap0(Native Method)
    at sun.management.HotSpotDiagnostic.dumpHeap(HotSpotDiagnostic.java:60)

5. 요약

이 문서에서는 힙 메모리 덤프를 얻는 여러 가지 방법을 설명합니다. 간단히 요약하면 다음과 같습니다.

  1. JVM 시작 매개변수를 지정하는 것이 좋습니다 HeapDumpOnOutOfMemoryError.
  2. 사용할 수 없는 경우 jmapjcmd, JVisualVM, JMX 등과 같은 다른 대안을 사용할 수 있습니다.
  3. 이 기사에 해당하는 코드는 GitHub 저장소를 참조하세요 .

추천

출처blog.csdn.net/renfufei/article/details/108785603