JVM 설정 도구: jinfo

jinfo (Java Configuration Info)는 JDK에 포함된 진단 도구로, 실행 중인 Java 프로세스의 JVM 설정 매개변수를 확인하거나 동적으로 수정하는 데 사용됩니다. 이 도구는 JVM 시작 시 매개변수와 시스템 속성을 확인하고 일부 매개변수를 실행 중에 동적으로 조정할 수 있습니다.

주의: jinfoJVM Attach 메커니즘에 의존하므로 다음 사항을 충족해야 합니다:

  • 대상 프로세스는 HotSpot JVM (OpenJDK / Oracle JDK)
  • 현재 사용자와 Java 프로세스 사용자가 일치하거나 root 권한이 필요
  • /tmp 디렉토리가 쓰기 가능 (.java_pid<PID> 소켓 파일 생성을 위해)
  1. 기본 구문
jinfo [옵션] <pid>
jinfo [옵션] <실행 파일> <코어 파일>
jinfo [옵션] [server_id@]<원격 서버 IP 또는 호스트명>

가장 자주 사용되는 형태는 첫 번째로, PID를 통해 로컬에서 실행 중인 Java 프로세스를 확인합니다.

  1. 핵심 기능 분류

기능 1: JVM 시작 매개변수 확인

기능 2: 시스템 속성 (-Dxxx) 확인

기능 3: 일부 부울형 JVM 매개변수 동적 수정 (제한적 지원)

  1. 주요 옵션 설명
옵션 설명
옵션 없음 기본 동작: -flags와 동일, JVM 시작 매개변수 표시
-flags 모든 JVM 시작 매개변수(기본값 및 명시적 설정 포함) 표시
-sysprops JVM의 시스템 속성(System.getProperties() 내용) 표시
-flag <name> 단일 JVM 매개변수의 현재 값을 확인
**`-flag [+ -]`**
-help 도움말 정보 표시
  1. 사용 예시

1. 모든 JVM 시작 매개변수 확인 (가장 일반적)

jinfo -flags <pid>

출력 예:

프로세스 ID 12345에 연결 중입니다, 잠시만 기다려주세요...
디버거 연결 성공.
서버 컴파일러 감지됨.
JVM 버전은 17.0.8+9-LTS

비기본 VM 플래그:
-XX:CICompilerCount=12
-XX:InitialHeapSize=268435456
-XX:MaxHeapSize=4294967296
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:+UseG1GC

주의: 비기본 값만 표시됩니다. 모든 매개변수를 보려면 -XX:+PrintFlagsFinal 옵션으로 애플리케이션을 시작하세요.

2. 단일 매개변수 값 확인

# 최대 힙 크기 확인
jinfo -flag MaxHeapSize 12345

# G1 GC 사용 여부 확인
jinfo -flag UseG1GC 12345

# PrintGC 활성화 여부 확인
jinfo -flag PrintGC 12345

출력 예:

-XX:MaxHeapSize=4294967296
-XX:+UseG1GC
-XX:-PrintGC

지원되는 매개변수 이름은 다음과 같이 얻을 수 있습니다:

  • -XX:+PrintFlagsFinal 옵션으로 시작하여 모든 매개변수 이름 확인
  • Oracle 공식 JVM 매개변수 목록 참조

3. 부울형 매개변수 동적 수정 (핵심 기능!)

주의: 일부 매개변수만 실행 중에 수정 가능하며, 주로 디버깅 및 진단용 매개변수입니다.

동적 수정 가능한 일반 매개변수:

매개변수 설명
PrintGC 간략한 GC 로그 출력
PrintGCDetails 상세 GC 로그 출력
PrintGCDateStamps GC 로그에 타임스탬프 추가
HeapDumpBeforeFullGC Full GC 전 힙 덤프 생성
HeapDumpAfterFullGC Full GC 후 힙 덤프 생성
PrintConcurrentLocks jstack -l 실행 시 동시 락 정보 출력

예시: 간략한 GC 로그 임시 활성화

# 간략한 GC 로그 활성화
jinfo -flag +PrintGC 12345

# 상세 GC 로그 활성화
jinfo -flag +PrintGCDetails 12345

# 비활성화
jinfo -flag -PrintGC 12345

용도: 운영 환경에서 문제 해결을 위해 재시작 없이 GC 로그를 임시로 활성화합니다!

동적 수정 불가능한 매개변수 (오류 발생):

  • -Xmx, -Xms (힙 크기)
  • -XX:NewRatio, -XX:SurvivorRatio
  • GC 알고리즘 (예: -XX:+UseG1GC-XX:+UseZGC)

수정 시 오류 발생:

Exception in thread "main" java.lang.reflect.InvocationTargetException
Caused by: com.sun.tools.attach.AgentLoadException: Target VM failed to initialize agent.

4. 시스템 속성 확인 (-Dxxx 매개변수)

jinfo -sysprops 12345

출력 예:

java.runtime.name = OpenJDK Runtime Environment
java.vm.version = 17.0.8+9-LTS
file.encoding = UTF-8
user.timezone = Asia/Seoul
app.env = prod
spring.profiles.active = prod

이는 Java 코드에서 System.getProperties().list(System.out); 호출과 동일합니다.

용도:

  • -Dfile.encoding=UTF-8 설정 확인
  • Spring Boot의 spring.profiles.active 확인
  • 사용자 정의 시스템 속성 검사
  1. 일반적인 문제 및 제한사항

1. "Unable to open socket file" 오류

원인은 jstack과 동일: Attach 메커니즘이 실패(컨테이너, Alpine, 읽기 전용 파일 시스템 등).

해결 방법:

  • /tmp 디렉토리 쓰기 가능 여부 확인
  • 동일한 사용자로 실행
  • 컨테이너 내에서는 ps와 시작 로그를 이용하여 매개변수 확인

2. 비부울 매개변수 수정 불가능

jinfo -flag부울형 매개변수JVM이 명시적으로 실행 중에 수정을 지원하는 것만 수정 가능합니다.

3. JDK 버전 차이

  • JDK 8: 많은 동적 매개변수 지원
  • JDK 11+: 일부 매개변수가 폐지되거나 동작 변경
  • JDK 17+: 컨테이너 지원 개선, 동적 수정 능력은 크게 변화 없음

권장: jinfo를 통해 매개변수를 수정하는 것은 임시 진단용으로만 사용하세요.

  1. 유용한 팁

팁 1: jps와 함께 빠르게 매개변수 확인

# 첫 번째 Java 프로세스의 GC 매개변수 확인
PID=$(jps -q | head -1)
jinfo -flag UseG1GC $PID
jinfo -flag MaxHeapSize $PID

팁 2: 임시 힙 덤프 활성화 (OOM 문제 해결)

# Full GC 전후에 자동으로 힙 덤프 생성(메모리 누수 분석용)
jinfo -flag +HeapDumpBeforeFullGC <pid>
jinfo -flag +HeapDumpAfterFullGC <pid>

주의: 덤프 파일은 기본 작업 디렉토리에 저장되며, 디스크 공간을 확인하세요!

팁 3: 컨테이너 지원 여부 확인 (JDK 8u191+)

jinfo -flag UseContainerSupport <pid>
# 출력: -XX:+UseContainerSupport는 활성화됨을 나타냅니다
  1. 동적 수정 가능한 매개변수 참고 (HotSpot)

다음 명령어로 실행 중에 수정 가능한 매개변수를 확인할 수 있습니다:

# Java 프로세스를 시작하면서 모든 매개변수 출력
java -XX:+PrintFlagsFinal -version | grep manageable

출력에서 manageable = true인 매개변수는 jinfo -flag로 동적 수정 가능합니다.

일반적인 manageable 매개변수:

bool PrintGC                            = false {manageable}
bool PrintGCDetails                     = false {manageable}
bool PrintGCDateStamps                  = false {manageable}
bool HeapDumpBeforeFullGC               = false {manageable}
bool HeapDumpAfterFullGC                = false {manageable}
bool PrintConcurrentLocks               = false {manageable}
  1. 최고의 실천 방안

  2. 진단 우선: jinfo -flags <pid>로 빠르게 JVM 설정 확인

  3. 운영 응급 처리: jinfo -flag +PrintGCDetails로 임시로 GC 로그 활성화

  4. 의존성 피하기: jinfo를 통해 매개변수를 수정하는 운영 절차 설계를 피하세요

  5. 컨테이너 환경: jinfo가 실패하면 시작 명령 또는 ConfigMap에서 매개변수 확인

태그: JVM jinfo HotSpot

7월 5일 00:04에 게시됨