본문 바로가기

리눅스

Java 프로세스의 메모리 사용량을 확인하는 방법

반응형

Java 프로세스의 메모리 사용량을 확인하는 방법

ps 명령어 사용

ps 명령어는 현재 실행 중인 모든 프로세스의 정보를 표시합니다.

ps 명령어를 사용하여 Java 프로세스의 PID를 확인합니다.

ps aux | grep -v grep | grep java
$ ps aux | grep -v grep | grep java
root       29670  0.2  2.2 5750736 181928 pts/1  Sl+  21:12   0:16 java -jar build/libs/demo-0.0.1-SNAPSHOT.jar

PID를 확인한 후 다음과 같이 ps 명령어를 사용하여 Java 프로세스의 메모리 사용량을 확인합니다.

ps -p <pid> -o rss,vsz
$ ps -p 29670 -o rss,vsz
  RSS    VSZ
181928 5750736

메모리 사용량은 RSS(Resident Set Size)와 VSZ(Virtual Memory Size) 등의 열에서 확인할 수 있습니다.

  • rss는 Resident Set Size로 프로세스가 실제 사용하는 메모리 양을 나타냅니다.
  • vsz는 Virtual Set Size로 프로세스가 요구하는 메모리 양을 나타냅니다.

/proc/<pid>/status 파일 사용

/proc/<pid>/status 파일에는 프로세스의 상태에 대한 정보가 포함되어 있습니다.

더보기

---

$ cat /proc/29670/status
Name:	java
Umask:	0022
State:	S (sleeping)
Tgid:	29670
Ngid:	0
Pid:	29670
PPid:	28550
TracerPid:	0
Uid:	0	0	0	0
Gid:	0	0	0	0
FDSize:	256
Groups:	0
NStgid:	29670
NSpid:	29670
NSpgid:	29670
NSsid:	28548
VmPeak:	 5750736 kB
VmSize:	 5750736 kB
VmLck:	       0 kB
VmPin:	       0 kB
VmHWM:	  197368 kB
VmRSS:	  181928 kB
RssAnon:	  159304 kB
RssFile:	   22624 kB
RssShmem:	       0 kB
VmData:	  282968 kB
VmStk:	     132 kB
VmExe:	       4 kB
VmLib:	   21432 kB
VmPTE:	     744 kB
VmSwap:	       0 kB
HugetlbPages:	       0 kB
CoreDumping:	0
THP_enabled:	1
Threads:	38
SigQ:	2/31295
SigPnd:	0000000000000000
ShdPnd:	0000000000000000
SigBlk:	0000000000000000
SigIgn:	0000000000000000
SigCgt:	2000000101005ccf
CapInh:	0000000000000000
CapPrm:	000001ffffffffff
CapEff:	000001ffffffffff
CapBnd:	000001ffffffffff
CapAmb:	0000000000000000
NoNewPrivs:	0
Seccomp:	0
Seccomp_filters:	0
Speculation_Store_Bypass:	vulnerable
SpeculationIndirectBranch:	always enabled
Cpus_allowed:	f
Cpus_allowed_list:	0-3
Mems_allowed:	00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list:	0
voluntary_ctxt_switches:	2
nonvoluntary_ctxt_switches:	0

---

다음과 같이 /proc/<pid>/status 파일을 사용하여 프로세스의 메모리 rss를 확인합니다.

cat /proc/<pid>/status | grep VmRSS

예를 들어, PID가 29670인 프로세스의 메모리 rss를 확인하려면 다음과 같이 입력합니다.

$ cat /proc/29670/status | grep VmRSS
VmRSS:	  181928 kB

위의 출력에서 VmRSS 값은 181928kB입니다. 따라서 이 프로세스는 실제 181928kB의 메모리를 사용하고 있습니다.

 

이 외에도 다양한 도구를 사용하여 메모리 rss를 확인할 수 있습니다. 예를 들어, top 명령어, htop 명령어, vmstat 명령어 등을 사용할 수 있습니다.

JVM 메모리 관리

출처-https://t1.daumcdn.net/cfile/tistory/2121BB33595349680D?original
출처-https://www.slideshare.net/dhaval201279/jvm-memory-management-diagnostics
출처-https://t1.daumcdn.net/cfile/tistory/216AE04C5654207F0A?original

JVM은 Java 애플리케이션을 실행하기 위해 다양한 메모리 영역을 사용합니다. JVM 메모리 영역은 크게 런타임 데이터 영역과 비 런타임 데이터 영역으로 나눌 수 있습니다.

 

런타임 데이터 영역은 Java 애플리케이션이 실행되는 동안 사용되는 메모리 영역입니다. 런타임 데이터 영역은 다음과 같은 영역으로 구성됩니다.

  • 힙 메모리(Heap)
    힙 메모리는 Java 객체를 저장하는 영역입니다. 힙 메모리는 Young Generation과 Old Generation으로 구분됩니다.
    • Young Generation
      Young Generation은 힙 메모리의 일부로 생성된 객체가 처음으로 할당되는 영역입니다. Young Generation은 Eden, Survivor,  Tenured로 구분됩니다.
      • Eden
        Eden은 Young Generation의 가장 큰 부분을 차지하는 영역으로 새로 생성된 객체가 처음으로 할당되는 영역입니다. Eden 영역의 객체는 Garbage Collection을 통해 주기적으로 제거됩니다.
      • Survivor
        Survivor는 Young Generation의 일부로 Eden 영역의 객체 중 살아남은 객체가 할당되는 영역입니다. Survivor 영역은 Minor GC가 발생할 때마다 Eden 영역의 객체 중 살아남은 객체를 절반씩 분배하여 사용합니다.
      • Tenured
        Tenured는 Young Generation의 일부로 Survivor 영역에서 살아남은 객체가 할당되는 영역입니다. Tenured 영역의 객체는 Major GC를 통해 제거됩니다.
    • Old Generation
      Old Generation은 Young Generation에서 살아남은 객체가 할당되는 영역입니다. Old Generation은 Major GC를 통해 주기적으로 제거됩니다.
  • 메서드 영역(Method Area)
    메서드 영역은 클래스의 메서드 정보를 저장하는 영역입니다. 메서드 영역은 JVM이 시작될 때 생성되며 종료될 때까지 유지됩니다.
  • 스택 메모리(Stack)
    스택 메모리는 함수 호출에 사용되는 메모리 영역입니다. 스택 메모리는 함수가 호출될 때마다 새 스택 프레임이 생성되고 함수가 종료될 때마다 스택 프레임이 제거됩니다.

비 런타임 데이터 영역은 다음과 같은 영역으로 구성됩니다.

  • 정적 데이터 영역
    정적 데이터 영역은 클래스의 정적 변수를 저장하는 영역입니다. 정적 데이터 영역은 JVM이 시작될 때 생성되며, 종료될 때까지 유지됩니다.
  • 네이티브 메모리(Native Method Stack)
    네이티브 메모리는 Java 애플리케이션이 네이티브 코드를 실행하는 데 사용하는 메모리 영역입니다. 네이티브 메모리는 JVM이 관리하지 않는 영역입니다.

JDK 17에서 변경된 점은 다음과 같습니다.

  • Metaspace 영역의 변경
    JDK 8 이전에는 정적 데이터 영역은 Permanent Generation 영역으로 구분되었습니다. JDK 8부터는 Metaspace 영역으로 변경되었습니다. Metaspace 영역은 JVM이 아닌 운영 체제에 의해 관리됩니다.
  • G1 GC의 개선
    G1 GC는 JDK 11부터 기본 GC로 사용되고 있습니다. JDK 17에서는 G1 GC의 성능과 안정성이 개선되었습니다.
  • ZGC GC의 추가
    ZGC GC는 JDK 17에 추가된 새로운 GC입니다. ZGC GC는 매우 빠른 GC 성능을 제공합니다.

JVM 메모리 영역은 Java 애플리케이션의 성능과 안정성에 중요한 영향을 미칩니다. 따라서 JVM 메모리 영역을 잘 이해하고 적절하게 관리하는 것이 중요합니다.

 

참고URL

- IBM Documentation : JVM(Java Virtual Machine)

- DigitalOcean Tutorial : Java (JVM) Memory Model - Memory Management in Java

- SAP Documentation : Configuration and Setup of SAP JVM

- Freshers Now : JVM (Java Virtual Machine) Architecture

- BESPIN GLOBAL Tech blog : Garbage Collection – 1부

 

728x90
반응형