반응형
기본 Xms Xmx
java -jar -Dspring.profiles.active=real xxx.jar
로 실행하고 있는 프로세스가 있다. 띄울 때 최소/최대 힙 사이즈를 안 줘서 기본값으로 어떻게 들고 있는지 궁금했다.
java -XX:+PrintFlagsFinal -version | grep -E "InitialHeapSize|MaxHeapSize"
size_t InitialHeapSize = 62914560
size_t MaxHeapSize = 994050048
위 명령어를 사용하면 현재 JVM의 기본 힙 설정을 알 수 있다.
각각은 바이트 단위이다. 따라서 좀 더 이해하기 쉽게 바꿔보면
- 바이트(Byte) -> 킬로바이트(Kilobyte):
- 1KB = 1024B
- 62914560 ÷ 1024 = 61440 KB
- 킬로바이트(Kilobyte) -> 메가바이트(Megabyte):
- 1MB = 1024KB
- 61440 ÷ 1024 = 60 MB
따라서, initialHeapSize가 62914560이라는 값은 60MB를 잡고 있다는 뜻이다.
또한 최대 값을 계산해보면
- 바이트(Byte) -> 킬로바이트(Kilobyte):
- 1KB = 1024B
- 994050048 ÷ 1024 = 970752 KB
- 킬로바이트(Kilobyte) -> 메가바이트(Megabyte):
- 1MB = 1024KB
- 970752 ÷ 1024 = 948 MB
따라서, maxHeapSize가 994050048 바이트라는 값은 약 948MB를 최대 값으로 설정했다는 것이다.
지금 메모리 현황 보기
free -h
total used free shared buff/cache available
Mem: 3.7G 933M 976M 137M 1.8G 2.3G
Swap: 2.0G 13M 2.0G
gc 관련 모니터링(jstat) 권한없어도 가능
jstat -gc <PID> <interval> <count>
jstat -gc 12345 1000 10 # 12345 PID의 JVM에 대해 1초 간격으로 10번 GC 정보를 출력
//
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC FGC
1024.0 1024.0 0.0 0.0 8192.0 1024.0 20480.0 8192.0 512.0 488.0 64.0 62.0 3 1
- S0C/S1C: Survivor space 0/1의 용량.
- EC: Eden 영역의 용량.
- OC: Old 영역의 용량.
- YGC/FGC: Young/Full GC의 발생 횟수.
OOM이 터질 때 자동으로 덤프를 뜨게 하는 옵션을 주려면 아래와 같은 옵션을 자바에 추가한다.
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/경로/heapdump.hprof
이미 뭔가 데드락이나 무한루프에 빠진 것 같다면 확인하기
각 스레드의 상태와 현재 실행 중인 코드를 볼 수 있음(권한 필요)
jstack <PID>
"main" #1 prio=5 os_prio=0 tid=0x00000000023f6000 nid=0x2c runnable [0x0000000002a1e000]
java.lang.Thread.State: RUNNABLE
at java.lang.Thread.sleep(Native Method)
at Example.main(Example.java:5)
현재 돌고 있는 프로세스의 덤프 뜨는 법
jmap이나 jcmd 명령어 사용(권한 필요)
sudo jmap -dump:format=b,file=/경로/heapdump.hprof <PID>
-- or
jcmd <PID> GC.heap_dump <경로>
// /proc/3272/root폴더에 권한이 없을 경우
Exception in thread "main" com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file /proc/3272/root/tmp/.java_pid3272: target process 3272 doesn't respond within 10500ms or HotSpot VM not loaded
at jdk.attach/sun.tools.attach.VirtualMachineImpl.<init>(VirtualMachineImpl.java:100)
at jdk.attach/sun.tools.attach.AttachProviderImpl.attachVirtualMachine(AttachProviderImpl.java:58)
at jdk.attach/com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:207)
at jdk.jcmd/sun.tools.jmap.JMap.executeCommandForPid(JMap.java:128)
at jdk.jcmd/sun.tools.jmap.JMap.dump(JMap.java:208)
at jdk.jcmd/sun.tools.jmap.JMap.main(JMap.java:114)
MAT(Eclipse Memory Analyzer Tool)
hprof파일을 얻었으면 분석 프로그램인 eclipse MAT 프로그램이 필요하다.
다운로드하고 hprof파일을 열어준다. hprof 파일의 용량이 클 수록 오래걸린다.
분석 보고서 이해하기
- Overview (개요): 메모리 상태, 누수 가능성, 가장 큰 객체 등을 요약하여 보여줌
- Dominator Tree: 힙 메모리의 최상위 점유자를 트리 구조로 보여주며 메모리 점유 비율이 큰 객체를 쉽게 파악 가능
- Histogram: 클래스별로 객체 수와 메모리 점유량
- Top Consumers: 메모리 사용량이 큰 객체 그룹
힙 분석 예시
- 메모리 누수 확인:
- Leak Suspects Report를 사용하면 누수 가능성이 있는 객체를 분석하여 보여줌
- "Path to GC Root" 기능을 사용해 메모리에서 해제되지 않은 객체의 참조 경로를 추적할 수 있음
- Dominator Tree 분석:
- Dominator Tree를 통해 메모리를 가장 많이 차지하는 객체 파악
- with outgoing references를 사용하여 참조 중인 객체들을 확인
- Histogram 분석:
- 클래스별로 객체 수와 메모리 점유율을 확인하여 특정 클래스가 메모리를 많이 사용하는지 파악
- 특정 클래스에서 메모리를 많이 사용하는 객체가 있다면, 이를 "List Objects -> with incoming references"로 추적 가능
728x90
반응형
'개발 > java' 카테고리의 다른 글
[java8+] 함수형 프로그래밍 @FunctionalInterface (0) | 2024.09.21 |
---|---|
Runnable vs Callable (0) | 2024.09.20 |
불변객체 만들기 ImmutableCollections.class (0) | 2024.09.14 |
[java] try with resources; close (1) | 2024.05.09 |
[java] 객체 소팅 시 비교하는 법 comparable, comparator (0) | 2024.05.08 |