programing

JVM 프로세스는 메모리를 어떻게 할당합니까?

newsource 2023. 10. 22. 20:05

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입니다enter image description here.

메타스케이프 사이즈는 89M 입니다.
enter image description here

즉, 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