CodeGym /행동 /JAVA 25 SELF /JVM 모니터링: JMX, VisualVM, Java Flight Recorder

JVM 모니터링: JMX, VisualVM, Java Flight Recorder

JAVA 25 SELF
레벨 63 , 레슨 3
사용 가능

1. JMX (Java Management Extensions): JVM 모니터링의 심장

모니터링은 애플리케이션을 위한 정기 건강검진과 같습니다. 로깅이 이미 발생한 일을 모두 기록하는 일기라면, 모니터링은 지금 이 순간 시스템의 상태를 보여 주는 계기 모음입니다. 예를 들어 온도, 맥박, 혈압, 혈당과 같은 생명 지표를 JVM 관점에서 확인하게 해 줍니다.

이를 통해 실제로 얼마나 많은 메모리가 사용되는지와 누수가 있는지, 몇 개의 스레드가 어떤 상태인지(대기, 실행, 차단)를 파악할 수 있습니다. 가비지 컬렉터가 얼마나 자주 동작하는지, CPU가 얼마나 바쁜지 확인하고, 메모리나 스레드 수의 갑작스러운 증가 같은 경고 신호를 제때 포착할 수 있습니다.

짧게 말해, 로깅은 이미 일어난 일을, 모니터링은 지금 일어나고 있는 일을 보여 줍니다.

JMX 기본: 무엇이고 왜 필요한가

JMX는 애플리케이션 내부에서 무슨 일이 일어나는지 관찰하고 일부를 제어할 수 있게 해 주는 Java 기술입니다. 이는 특별한 객체인 MBean(Management Bean)을 통해 동작합니다. JVM 내부의 ‘센서’와 ‘스위치’처럼, 어떤 것은 시스템 상태를 보여 주고, 어떤 것은 약간의 조정을 가능하게 합니다.

JMX를 사용하면 JVM에 현재 얼마나 많은 메모리가 할당되어 있는지, 활성 스레드는 몇 개인지, 가비지 컬렉션에 얼마나 시간이 드는지 등을 코드 수정이나 애플리케이션 재시작 없이 알 수 있습니다.

동작 방식

JVM에는 기본적으로 많은 MBean이 포함되어 있으며 다음과 같은 정보를 제공합니다:

  • 메모리(heap, non-heap);
  • 가비지 컬렉터(GC);
  • 스레드;
  • 클래스(로드/언로드 개수);
  • 그리고 JVM 자체 정보(버전, 시작 매개변수).

JMX는 자동차의 계기판과 같습니다. 속도, RPM, 엔진 온도를 보듯, 표준 센서(MBean)를 통해 다양한 상태를 확인할 수 있습니다.

JMX에 접근하는 방법

가장 간단한 방법은 JDK에 포함된 표준 유틸리티 JConsole을 사용하는 것입니다.

JConsole 실행

  1. 터미널/명령 프롬프트를 엽니다.
  2. 다음 명령을 실행합니다:
    jconsole
    
  3. 모니터링할 Java 프로세스를 선택합니다(예: 여러분의 애플리케이션).

JConsoleJMX를 통해 JVM에 연결하고, 메모리 사용량, 스레드 수, 가비지 컬렉터 활동 등과 같은 그래프와 표를 보여 줍니다.

예시: 메모리와 스레드 보기

JConsole에서 "Memory""Threads" 탭을 열어 보세요. 사용 중인 메모리 양의 변화, 현재 살아 있는 스레드 수, 활성/대기 상태 등을 확인할 수 있습니다.

사용자 정의 MBean

처리된 주문 수와 같은 자체 메트릭을 모니터링하기 위해 사용자 정의 MBean을 만들 수도 있습니다. 다만 이는 고급 주제이며, 표준 MBean만으로도 매우 많은 정보를 얻을 수 있습니다.

2. VisualVM — 시각적 모니터링과 프로파일링

JConsole이 ‘계기판’이라면, VisualVM은 X-레이, MRI, 혈액 검사까지 갖춘 진단 센터입니다. 모니터링뿐 아니라 애플리케이션을 프로파일링하고 heap dump를 캡처하며, 누수를 분석하고 시간이 가장 많이 소요되는 메서드를 확인할 수 있습니다.

VisualVM 설치 및 실행

  • VisualVMJDK에 포함되어 있습니다(일반적으로 jvisualvm). 최신 버전은 visualvm.github.io에서 다운로드할 수 있습니다.
  • 다음 명령으로 실행합니다:
    jvisualvm
    
  • 실행 후, 로컬 머신에서 실행 중인 모든 Java 프로세스 목록이 보입니다.

프로세스에 연결하기

  1. 목록에서 자신의 프로세스(예: Main 또는 MyApp)를 찾습니다.
  2. 두 번 클릭하면 해당 프로세스 정보 탭이 열립니다.
  3. 완료! 이제 다음을 확인할 수 있습니다:
    • 실시간 CPU 및 메모리 사용량.
    • 스레드 수와 상태.
    • 로드된 클래스 목록.
    • heap dumpthread dump 캡처.

VisualVM의 주요 기능

VisualVM으로 메모리 사용( heapnon-heap)을 관찰할 수 있습니다. 그래프를 통해 사용량이 증가하는지 안정화되는지 확인할 수 있습니다. 가비지 컬렉션을 확인하려면 "Perform GC" 버튼을 누르세요 — JVM이 즉시 메모리를 정리하려고 시도합니다. heap dump(메모리 스냅샷)를 생성해 누수를 조사할 수도 있습니다.

스레드 상태도 보여 줍니다. 몇 개가 실행 중인지, 어떤 스레드가 동작/대기/차단 상태인지 확인할 수 있습니다. deadlock이 발생했다면, VisualVM이 이를 감지하고 상호 교착을 보여 줍니다.

더 깊은 분석을 위해 프로파일링을 사용할 수 있습니다. 가장 많은 CPU 시간이나 메모리를 소비하는 ‘핫’ 메서드를 확인할 수 있어, 예상치 못한 성능 저하를 진단하는 데 유용합니다.

예시: 미니 애플리케이션 모니터링

public class MemoryLeakDemo {
    public static void main(String[] args) throws InterruptedException {
        List<byte[]> memoryConsumers = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            memoryConsumers.add(new byte[1024 * 1024]); // 1 MB
            Thread.sleep(100); // 그래프가 더 부드럽게 보이도록 잠시 대기
        }
        System.out.println("완료! VisualVM에서 확인하는 것을 잊지 마세요 :)");
        Thread.sleep(60000); // 분석을 위해 애플리케이션을 유지
    }
}

이제:

  1. 프로그램을 실행합니다.
  2. VisualVM을 열고, 프로세스에 연결합니다.
  3. 메모리 사용량이 어떻게 증가하는지 확인합니다.
  4. heap dump를 찍고, 메모리를 차지하는 배열을 찾아봅니다.

3. Java Flight Recorder (JFR): JVM을 위한 블랙박스

JFR란?

Java Flight RecorderJVM에 내장된 애플리케이션 동작 이벤트 수집 도구입니다. 일종의 “블랙박스”로서, JFRJVM에서 일어나는 일을 기록하여 이후 병목이나 인시던트의 원인을 찾을 수 있게 해 줍니다.

JFR이 수집하는 것:

  • GC 이벤트;
  • 스레드 정보;
  • 메서드 호출 빈도와 시간 프로파일;
  • 일시 중지와 지연;
  • 예외와 오류.

JFR 활성화 방법

Java 11+에서는 JFROpenJDK에 기본 포함되어 있습니다.

JFR과 함께 실행

java -XX:StartFlightRecording=filename=recording.jfr,duration=60s,settings=profile -jar MyApp.jar
  • filename=recording.jfr — 기록 파일 저장 위치.
  • duration=60s — 기록할 시간.
  • settings=profile — 상세 수준(default, profile, continuous).

결과 보기

.jfr 파일 분석에는 JDK Mission Control (JMC)을 사용합니다:

  1. JMC 다운로드: jdk.java.net/jmc
  2. recording.jfr 파일을 엽니다.
  3. 그래프, ‘핫’ 메서드, GC 일시 정지와 스레드 활동을 분석합니다.

예시: “블랙박스” 기록하기

  1. JFR을 켜고 애플리케이션을 실행합니다(위 명령 참조).
  2. JDK Mission Control을 열어 기록 파일을 로드합니다.
  3. CPU/메모리 핫스팟, 가비지 컬렉션 빈도, 활성 스레드 수 등을 평가합니다.

4. 실습: 애플리케이션 모니터링

import java.util.ArrayList;
import java.util.List;

public class MonitoringExample {
    public static void main(String[] args) throws InterruptedException {
        List<byte[]> memory = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            memory.add(new byte[2 * 1024 * 1024]); // 2 MB
            Thread.sleep(500);
        }
        // 스레드를 시작합니다
        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(1000);
                    System.out.println("백그라운드 스레드가 동작 중...");
                } catch (InterruptedException e) {
                    break;
                }
            }
        }).start();

        Thread.sleep(20000); // 모니터링을 위해 애플리케이션을 유지
    }
}

진행 방법:

  • 프로그램을 실행합니다.
  • VisualVM을 열어 프로세스를 찾고, 메모리 그래프와 스레드를 확인합니다.
  • heap dumpthread dump를 시도해 보세요.
  • 고급: JFR을 켠 채 실행하고 JMC에서 결과를 확인합니다.

5. 유용한 팁

모니터링 도구 비교 표

도구 적합한 용도 실행 방법 특징
JConsole (JMX) JVM 기본 메트릭, 스레드, GC
jconsole
간단하며 JDK에 포함
VisualVM 모니터링, 프로파일링, heap dump
jvisualvm
그래프, 메모리/CPU 분석
Java Flight Recorder JVM 이벤트 심층 분석
java -XX:StartFlightRecording...
JMC에서 분석, “블랙박스”
JDK Mission Control JFR 파일 뷰어 별도 프로그램 자세한 분석과 리포트

권장 사항

  • 프로덕션뿐 아니라 테스트 단계에서도 모니터링하세요. 메모리 누수와 ‘멈춘’ 스레드를 더 일찍 잡을 수 있습니다.
  • Heap dump는 어렵지 않습니다! 누수가 의심되면 메모리 덤프를 찍어 VisualVM에서 분석하세요.
  • JFR 실험을 두려워하지 마세요. 당장 모든 것이 이해되지 않더라도, 이벤트와 그래프가 병목을 찾는 데 도움을 줍니다.
  • JMX는 프로그램적으로도 사용할 수 있습니다. 예를 들어 메트릭을 Prometheus/Grafana로 전송할 수 있습니다.
  • 프로파일링은 상시 가동용이 아닙니다. 필요한 경우에만 프로파일러를 선택적으로 켜지 않으면 애플리케이션이 느려질 수 있습니다.

6. JVM 모니터링 시 흔한 실수

오류 №1: 전혀 모니터링하지 않음. 많은 초보자는 애플리케이션이 ‘동작한다’면 괜찮다고 생각합니다. 실제로는 메모리와 스레드 문제는 부하 상황이나 시간이 지난 뒤에 나타나는 경우가 많습니다. 최소한 주기적으로라도 VisualVM/JConsole을 열어 확인하세요.

오류 №2: 대형 애플리케이션에서 준비 없이 heap dump를 찍는 것. Heap dump는 기가바이트 단위로 커질 수 있고 프로세스를 몇 초 동안 ‘멈추게’ 할 수 있습니다. 테스트 환경에서 수행하거나, 프로덕션이라면 ‘한가한’ 시간대에 하세요.

오류 №3: GC와 스레드 지표를 무시함. GC에 지속적으로 많은 시간이 소모된다면 경고 신호입니다! 스레드 수가 계속 증가한다면 스레드 누수를 의심하세요.

오류 №4: 모니터링 결과를 분석하지 않음. VisualVM을 열기만 해서는 충분하지 않습니다. 어떤 객체가 메모리를 차지하는지, 어떤 메서드가 CPU를 ‘잡아먹는지’, 왜 deadlock이 생기는지 확인하세요. 스택 트레이스와 원인을 면밀히 파악하세요.

오류 №5: 이해 없이 프로덕션에서 프로파일러를 사용함. 프로파일링은 애플리케이션을 크게 느리게 만들 수 있습니다. 진단이 필요할 때만 켜고, ‘상시’로 두지 마세요.

1
과제
JAVA 25 SELF, 레벨 63, 레슨 3
잠금
탐정
탐정
1
과제
JAVA 25 SELF, 레벨 63, 레슨 3
잠금
비행 관제사
비행 관제사
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION