글 검색

공개된 글의 제목과 본문을 검색합니다.

    닫기 Esc

    1. Threadm Dump와 Stack Trace 정보#

    • Java 애플리케이션이 실행되면 각각의 스레드는 고유한 Stack 공간을 할당받는다.
    • Stack에 포함된 정보는 메소드 호출정보가 순서대로 저장이 되고, Primitive 형식의 지역 변수(로컬) 정보가 저장된다.
    • 동적 생성 객체 정보는 Heap에 저장된다.
    • Call Stack은 메소드가 호출된 순서대로 각각의 스레드마다 순서대로 저장된다.
      • 가장 마지막에 호출되어 실행되고 있는 메소드가 가장 상위에 저장되는 구조이다.
    • Thread Dump를 생성하면 가장 위에 표시된 메소드가 가장 최근에 수행되고 있는 메소드이며, 아래로 내려갈수록 상위 메소드를 호출한 부모 메소드가 표시된다.
    • Thread Dump 파일 안에는 Thread가 실행되는지 Block되었는지 등의 실행 상태와 Lock을 보유한 객체 정보 등도 함께 제공한다.
    • 스레드 덤프 파일 생성은 kill -3 <pid>로 생성이 가능하다.

    2. Heap 메모리 구조#

    2.1 Young Generation#

    • 신규 생성 객체가 존재하며, Eden, Survive0, Survive1영역으로 나뉘어져 있다.
    • 빠르게 객체가 생겼다가 사라지는 영역이다.
    • 더 이상 참조되지 않는 객체는 Young GC(Minor GC)에 의해 제거된다.

    2.2 Old Generation#

    • Young Generation에서 GC 되지않고 살아남은 객체가 이동하는 영역으로 오랫동안 객체가 존재한다.
    • 더 이상 참조되지 않는 객체는 Full GC(Major GC)에 의해 제거된다.

    2.3 Permanent Generation, Meraspace#

    • Heap에 있는 객체에 대한 메타데이터 정보가 저장된다.
    • 기본적으로 JVM마다 64MB의 공간을 할당한다.
    • PermGen 영역은 Heap영역은 아니며, Full GC 발생 시 GC를 통해 메모리가 회수되는 영역이다.

    3. Heap Dump 정보#

    3.1 Heap Dump 파일이란?#

    • Heap Dump는 Java의 Heap메모리에 동적으로 생성된 객체에 대한 정보를 특정 시점에 스냅샷을 뜬 정보다.
    • 생성된 객체와 그의 필드정보를 제공한다.
    • 어떤 스레드가 어떤 Object를 사용하고 있는지에 대한 정보를 함게 파악할 수 있다.
    • Heap Dump는 특정 시점의 스냅샷정보이기에 언제 객체가 할당되고, 어떤 메소드에 의해 할당되었는지에 대한 정보는 포함하지 않는다.

    3.2 Heap Dump 파일은 어디에 사용되는가#

    • Heap Dump 파일을 이용하여 분석하게 되면 OOME가 발생한 Java 애플리케이션에 대해 원인을 분석가능하다.
      • 가장 메모리를 많이 사용하는 객체가 무엇인지 알 수 있다.
    • Java 애플리케이션에서 메모리 정리를 제대로 하지 않아 시간에 따라 메모리가 점점 증가하는 메모리 누수 현상은 하나의 Heap Dump 파일 가지고는 분석이 쉽지 않다.
      • 전문 프로파일링 도구가 필요하다.
    • 가장 메모리를 많이 사용하고 있는 객체로 부터 Memory Leak을 추정할 수 있다.
      • 2개 이상의 Heap Dump 파일을 비교해보면 메모리 누수 의심 객체를 파악할 수 있다.

    3.3 Heap Dump 파일의 종류#

    • Heap Dump 파일의 종류는 크게 IBM과 Sun 계열로 나뉠 수 있다.

    IBM 계열#

    • Object의 유형과 크기 및 객체 간의 관계만 포함하고 있다.

    Sun 계열#

    • 오브젝트 안에 있는 필드에 있는 값을 조사할 수 있고, 덤프 수행 시점의 마지막 실행 메소드도 알 수 있다.
    • 덤프파일의 크기가 크다.

    3.4 Heap Dump 파일 생성 방법#

    shell
    jcmd <pid> GC.heap_dump filename=<filename>
    jmap -dump:live,format=b,file=heapdump.hprof <pid>
    • Heap Dump를 수행하게 되면 GC가 수행되고 나서 메모리의 Snapshot을 수행하기에 사용하지 않는 객체는 모두 GC되어 사라지고 Live 객체에 대한 정보만 Snapshot에 저장이 된다.
      • jmap옵션에 live옵션 빼면 사용하지 않는 객체도 Snapshot이 가능하다.
    shell
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=경로
    • 수동으로 덤프를 만드는것이 아닌 OOME 발생 시 자동으로 덤프를 생성하는 옵션이다.
    • Heap Dump는 GC의 동반을 수행할 뿐아니라 전체 Heap에 대한 Snapshot을 만드는 과정이므로 애플리케이션이 동작중인 경우에는 주의를 해야한다.

    4. 객체 참조#

    • 객체는 GC root 객체로부터 참조되면 GC 대상이 아니다.
    • 메모리 누수는 더이상 사용되지 않는 객체가 계속해서 GC root로부터 연결되어 참조가 남아서 GC가 되지 않고 유지되어서 발생한다.

    GC root의 종류#

    • System Class Loader에 의해 로딩된 클래스
    • Live Thread
    • 로컬변수 or 파라미터
    • JNI 메소드의 로컬변수 또는 파라미터
    • 전역 JNI 참조변수
    • Monitor로 사용된 객체
    • JVM이 유지하는 객체: System Class Loader나 Exception 클래스 Custom Class Loader 등등
    전체 글 둘러보기