데이터 엔지니어링

패스트캠퍼스 환급챌린지 49일차: 데이터엔지니어링 초격차 강의 후기

Big Byte 2025. 5. 19. 23:07

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.

 

JVM 상태 이상 감지! 실전 모니터링 완전 정복 🛠️🩺

 

안녕하세요, 여러분! 🔥

 

지난 시간에는 JMX를 통해 JVM 내부를 들여다보는 방법을 배웠습니다. 마치 자동차의 계기판과 같았죠? 🚗 오늘은 그 계기판의 수치들을 실제로 어떻게 읽고 해석하여 우리 애플리케이션의 건강 상태를 진단하는지, 즉 JVM 모니터링의 실전 기술들을 파헤쳐 보겠습니다!

 

JVM 모니터링은 마치 의사가 환자를 진찰하듯, 시스템의 병목 지점을 찾고, 장애를 예방하며, 성능을 최적화하는 데 필수적인 과정입니다. 🩺 우리가 JMX라는 창을 통해 JVM 내부를 들여다볼 준비가 되었다면, 이제 무엇을 어떻게 관찰해야 할지 알아봅시다!

오늘 우리가 함께 살펴볼 JVM 모니터링의 핵심 내용은 다음과 같습니다:

  • Thread 모니터링 🧵 (Thread Dump, 주요 Metrics)
  • Memory 모니터링 🧠 (Heap Dump, 주요 Metrics)
  • GC 모니터링 🧹 (GC Log 활성화 & 분석, 주요 Metrics, 간단 실습)
  • Crash Dump 분석 💥 (hs_err_pid 파일, 생성 옵션 및 미생성 시 대처)

자, 그럼 지금부터 JVM의 건강 상태를 꼼꼼히 체크해볼까요? 출발! 

 

 

Thread 모니터링 🧵

애플리케이션의 실제 '일꾼'인 스레드! 👷‍♀️👷‍♂️ 스레드가 너무 많거나, 특정 스레드가 오랫동안 작업을 점유하거나, 데드

락(Deadlock) 상태에 빠지면 애플리케이션 전체 성능에 치명적인 영향을 줄 수 있습니다.

  • Thread Dump (스레드 덤프):
    • 무엇인가요? 특정 시점에 JVM 내 모든 스레드의 상태와 스택 트레이스(호출 이력)를 보여주는 스냅샷입니다. 📸
    • 언제 사용하나요? 애플리케이션 응답 없음, CPU 사용량 과다, 데드락 의심 상황 등에서 원인 분석에 사용됩니다.
    • 어떻게 만드나요?
      • jstack <pid>: JDK에 포함된 명령어 (가장 일반적)
      • VisualVM, JConsole: GUI 도구를 통해 생성 가능
      • kill -3 <pid> (Linux/macOS): 표준 출력으로 스레드 덤프를 보냅니다. (애플리케이션 로그에 찍히도록 설정 가능)
    • 무엇을 봐야 하나요? BLOCKED, WAITING, TIMED_WAITING 상태의 스레드와 그 스레드가 대기하고 있는 락(lock) 정보, 과도하게 반복되는 스택 트레이스 등을 주로 확인합니다.
  • 주요 Thread Metrics (JMX):
    • JMX MBean java.lang:type=Threading 을 통해 실시간 스레드 정보를 확인할 수 있습니다.
    • ThreadCount: 현재 활성 스레드 수
    • DaemonThreadCount: 데몬 스레드 수
    • PeakThreadCount: JVM 시작 후 최대 스레드 수
    • DeadlockedThreads: 데드락 상태인 스레드 ID 배열 (발견 시 즉시 조치 필요!)

VisualVM - Thread Dump

Memory 모니터링 🧠

메모리는 애플리케이션의 작업 공간입니다. 💾 메모리 누수(Memory Leak)가 발생하거나, 힙 크기 설정이 부적절하면 OutOfMemoryError (OOME)가 발생하여 애플리케이션이 중단될 수 있습니다.

  • Heap Dump (힙 덤프):
    • 무엇인가요? 특정 시점에 JVM 힙 메모리 영역에 있는 모든 객체 정보를 담고 있는 스냅샷입니다. 🕵️‍♂️
    • 언제 사용하나요? OutOfMemoryError 발생 원인 분석, 메모리 누수 의심 상황에서 사용됩니다.
    • 어떻게 만드나요?
      • jmap -dump:format=b,file=heap.hprof <pid>: JDK 명령어
      • VisualVM, JConsole: GUI 도구를 통해 생성 가능
      • JVM 옵션: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/heapdump.hprof (OOME 발생 시 자동으로 힙 덤프 생성)
    • 분석 도구: Eclipse MAT (Memory Analyzer Tool), VisualVM 등을 사용하여 어떤 객체가 메모리를 많이 차지하는지, 누수 지점은 어디인지 분석합니다.
  • 주요 Memory Metrics (JMX):
    • java.lang:type=Memory:
      • HeapMemoryUsage: 전체 힙 메모리 사용량 (init, used, committed, max)
      • NonHeapMemoryUsage: 전체 논힙 메모리 사용량
    • java.lang:type=MemoryPool,name=* (예: Eden Space, Survivor Space, Old Gen): 각 메모리 풀별 사용량

 

GC 모니터링 🧹

GC는 JVM의 자동 메모리 관리자이지만, GC 활동이 너무 잦거나 GC로 인한 중단 시간(Pause Time)이 길어지면 애플리케이션 성능에 영향을 줍니다.

  • GC Log (GC 로그):
    • 무엇인가요? GC 활동에 대한 상세 정보를 기록한 로그 파일입니다. 📜
    • 어떻게 활성화하나요? JVM 시작 옵션을 통해 설정합니다.
      • Java 9 이상: -Xlog:gc*:file=gc.log:time,level,tags (표준화된 로깅)
      • Java 8 이하 (예시): -verbose:gc -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps
    • 무엇을 담고 있나요? GC 발생 시간, GC 종류(Minor/Major GC), 각 세대별 메모리 변화량, GC 수행 시간, 중단 시간 등을 포함합니다.
    • GC Log Analyzer: GCEasy, GCViewer 같은 도구를 사용하면 GC 로그를 시각화하고 분석하기 용이합니다.
  • 주요 GC Metrics (JMX):
    • java.lang:type=GarbageCollector,name=* (예: PS Scavenge for Young GC, PS MarkSweep for Old GC):
      • CollectionCount: 해당 GC가 발생한 횟수
      • CollectionTime: 해당 GC에 소요된 누적 시간 (ms)
  • GC Log 실습:
    1. 간단한 Java 애플리케이션(예: 객체를 계속 생성하고 해제하는)을 준비합니다.
    2. 위의 GC 로그 활성화 옵션을 주고 애플리케이션을 실행합니다.
    3. 생성된 gc.log 파일을 열어 GC가 언제, 어떻게 발생하는지, 중단 시간은 얼마나 되는지 직접 확인해보세요! 👣

 

Crash Dump 분석 💥 (hs_err_pid 파일)

JVM이 예기치 않게 비정상적으로 종료(Crash)될 경우, 그 원인을 파악할 수 있는 단서를 담은 파일이 생성됩니다.

  • hs_err_pid<PID>.log 파일:
    • JVM Crash 발생 시 생성되는 텍스트 파일로, 에러 발생 시점의 스레드 정보, 스택 트레이스, 네이티브 프레임, 메모리 맵, 시스템 정보 등 다양한 디버깅 정보를 담고 있습니다. 😱
    • 이 파일을 분석하여 JVM이 왜 갑자기 죽었는지 (예: Native Code 문제, JVM 버그 등) 추론할 수 있습니다.
  • Crash Dump 파일 옵션:
    • -XX:ErrorFile=/path/to/hs_err_pid%p.log: hs_err_pid 파일이 생성될 경로와 파일명을 지정할 수 있습니다. (%p는 프로세스 ID로 치환)
  • Crash Dump가 남지 않는다면?:
    • kill -9 <pid> (SIGKILL): OS 레벨에서 프로세스를 강제 종료하면 JVM이 Crash Dump를 남길 기회가 없습니다. (가장 흔한 원인!)
    • 디스크 공간 부족 또는 권한 문제: 지정된 경로에 파일을 생성할 수 없는 경우.
    • -XX:-CreateCoredump 옵션 (Java 8 이전): 코어 덤프 생성을 비활성화한 경우 (hs_err_pid 파일과는 별개지만, Crash 시점의 상세 분석을 위한 코어 덤프도 중요할 수 있습니다).
    • 애플리케이션이 System.exit()으로 정상 종료되거나, OOM Killer에 의해 OS가 프로세스를 종료시키는 경우에도 hs_err_pid 파일이 남지 않을 수 있습니다.

정리하며 📝

오늘은 JVM의 건강 상태를 진단하기 위한 다양한 모니터링 기법을 살펴보았습니다!

  • Thread 모니터링 🧵: Thread Dump (jstack, kill -3)로 병목 지점 확인, JMX로 스레드 수치(ThreadCount, DeadlockedThreads) 모니터링.
  • Memory 모니터링 🧠: Heap Dump (jmap, OOME 옵션)로 누수 분석, JMX로 메모리 사용량(HeapMemoryUsage) 추적.
  • GC 모니터링 🧹: GC Log (JVM 옵션) 활성화 및 분석 도구 활용, JMX로 GC 성능 지표(CollectionCount, CollectionTime) 확인.
  • Crash Dump 💥: hs_err_pid 파일로 JVM 비정상 종료 원인 추적, 미생성 시 원인 파악 (특히 kill -9 주의).

이러한 모니터링 기법들은 JMX를 통해 제공되는 데이터를 기반으로 하거나, JDK에 포함된 도구들을 활용합니다. 꾸준한 모니터링과 분석을 통해 애플리케이션의 안정성과 성능을 한층 끌어올릴 수 있을 거예요!

 

 

오늘도 JVM의 깊숙한 곳까지 탐험하시느라 정말 수고 많으셨습니다! 💪 꾸준한 관심과 학습으로 애플리케이션의 건강을 지키는 든든한 개발자가 되시길 바랍니다. 다음 시간에도 유익한 내용으로 만나요! 즐거운 코딩 되세요! 🚀

https://abit.ly/lisbva