JVM 프로세스는 메모리를 어떻게 할당합니까?
JVM 프로세스가 자체 메모리를 할당하는 방법을 이해하는 데 약간의 차이가 있습니다.제가 아는 한,
RSS = Heap size + MetaSpace + OffHeap size
여기서 OffHeap은 스레드 스택, 직접 버퍼, 매핑된 파일(라이브러리 및 항아리) 및 JVM 코드 자체로 구성됩니다.
현재 Java 애플리케이션(Spring Boot + Infinispan)을 분석하려고 하는데 RSS가 779M(도커 컨테이너에서 실행되므로 pid 1은 괜찮습니다):
[ root@daf5a5ae9bb7:/data ]$ ps -o rss,vsz,sz 1
RSS VSZ SZ
798324 6242160 1560540
에 따르면jvisualvm
, 커밋된 힙 크기는 374M입니다.
즉, OffHeap 메모리의 799M - (374M + 89M) = 316M을 설명하고자 합니다.
제 앱에는 평균 36개의 라이브 스레드가 있습니다.
이러한 각 스레드는 1M을 소비합니다.
[ root@fac6d0dfbbb4:/data ]$ java -XX:+PrintFlagsFinal -version |grep ThreadStackSize
intx CompilerThreadStackSize = 0
intx ThreadStackSize = 1024
intx VMThreadStackSize = 1024
그래서 여기에 36M을 추가할 수 있습니다.
앱에서 다이렉트 버퍼를 사용하는 곳은 NIO뿐입니다.JMX에서 볼 수 있는 바로는 리소스가 많이 소모되지 않습니다. 98K에 불과합니다.
마지막 단계는 지도에 그려진 입술과 항아리입니다.하지만 말에 의하면pmap
(전체 출력)
[ root@daf5a5ae9bb7:/data ]$ pmap -x 1 | grep ".so.*" | awk '{ sum+=$3} END {print sum}'
12896K
플러스로
root@daf5a5ae9bb7:/data ]$ pmap -x 1 | grep “.jar" | awk '{ sum+=$3} END {print sum}'
9720K
여기는 2천만밖에 없습니다.
따라서 316M - (36M + 20M) = 260M :(
내가 뭘 놓쳤는지 아는 사람?
접근 방법:
Java HotSpot Native Memory Tracking(NMT)을 사용할 수 있습니다.
이것은 JVM에 의해 할당된 메모리의 정확한 목록을 제공할 수 있으며, 여러 영역 힙, 클래스, 스레드, 코드, GC, 컴파일러, 내부, 심볼, 메모리 추적, 풀링된 자유 청크 및 알 수 없는 영역으로 나뉩니다.
용도:
다음으로 응용 프로그램을 시작할 수 있습니다.
-XX:NativeMemoryTracking=summary
.현재 힙에 대한 관찰은 다음과 같이 수행할 수 있습니다.
jcmd <pid> VM.native_memory summary
.
jcmd/pid를 찾을 위치:
기본 Oped에서Ubuntu에서 JDK 설치는 다음에서 확인할 수 있습니다./usr/bin/jcmd
.
달리기만 하면jcmd
매개 변수 없이 실행 중인 Java 애플리케이션 목록을 얻을 수 있습니다.
user@pc:~$ /usr/bin/jcmd
5169 Main <-- 5169 is the pid
출력:
그러면 다음과 같은 모양으로 힙에 대한 전체 개요를 볼 수 있습니다.
총계: reserved=664192KB, committed=253120KB <-- 네이티브 메모리 추적에 의해 추적되는 총 메모리
Java 힙(예약=516096KB, 커밋=204800KB) <--- Java 힙
(mmap: 예약 = 516096KB, 커밋 = 204800KB)
클래스(예약 = 6568KB, 커밋 = 4140KB) <--- 클래스 메타데이터
(classes #665) <--- 로드된 클래스의 수
(malloc=424KB, #1000) <--malloc'd 메모리, #malloc의 수
(mmap: 예약 = 6144KB, 커밋 = 3716KB)
스레드(예약 = 6868KB, 커밋 = 6868KB)(thread #15) <--- 스레드 수
(스택: reserved=6780KB, committed=6780KB) <--- 스레드 스택에서 사용하는 메모리
(malloc=27KB, #66)
(arena=61KB, #30) <--- 리소스 및 핸들 영역
코드(예약 = 102414KB, 커밋 = 6314KB)
(malloc=2574KB, #74316)
(mmap: reserved=99840KB, 커밋=3740KB)
GC(예약 = 26154KB, 커밋 = 24938KB)
(malloc=486KB, #110)
(mmap: reserved=25668KB, 커밋=24452KB)
컴파일러(예약 = 106KB, 커밋 = 106KB)
(malloc=7KB, #90)
(arena=99KB, #3)
내부(예약=586KB, 커밋=554KB)
(malloc=554KB, #1677)
(mmap: reserved=32KB, committed=0KB)
기호(예약 = 906KB, 커밋 = 906KB)
(malloc=514KB, #2736)
(arena=392KB, #1)
메모리 추적(예약=3184KB, 커밋=3184KB)
(malloc=3184KB, #300)
풀링된 사용 가능한 청크(예약=1276KB, 커밋=1276KB)
(malloc=1276KB)
알 수 없음(예약=33KB, 커밋=33)KB)
(arena=33KB, #1)
여기에는 JVM에서 사용하는 다양한 메모리 영역에 대한 자세한 개요가 나와 있으며 예약 및 커밋된 메모리도 표시됩니다.
메모리 소비 목록을 더 자세히 알려주는 기술은 없습니다.
추가 읽기:
사용할 수도 있습니다.-XX:NativeMemoryTracking=detail
더 많은 것과 결합하여jcmd
명령들.자세한 설명은 Java Platform, Standard Edition Troubleshooting Guide - 2.6 The jcmd Utility에서 확인할 수 있습니다.다음을 통해 가능한 명령을 확인할 수 있습니다."jcmd <pid> help"
언급URL : https://stackoverflow.com/questions/35502348/how-does-a-jvm-process-allocate-its-memory
'programing' 카테고리의 다른 글
그룹화되지 않은 Oracle 결과: (0) | 2023.10.22 |
---|---|
문자열을 대문자로 분할 (0) | 2023.10.22 |
jQuery .close()와 비슷하지만 후손을 횡단합니까? (0) | 2023.10.22 |
PL/MySQL이 존재합니까? (0) | 2023.10.22 |
C에서 주(공)와 주()의 차이 (0) | 2023.10.22 |