Backend/Spring+Boot

SpringBoot 내장톰캣 JVM 메모리 default 값

findmypiece 2021. 11. 15. 01:45
728x90

일단 SpringBoot 환경에서 패키징 결과물로 생성된 jar 파일을 실행할 때 실행옵션을 주면 JVM 메모리를 설정할 수 있다. 

java -jar -Xms1024M -Xmx1024M app.jar

그 외 톰캣이 구동될 때 참조하는 CATALINA_OPTS, JAVA_OPTS 와 같은 환경변수에 -Xms1024M -Xmx1024M 를 지정해놔도 된다. 알다시피 Xms 는 초기힙사이즈, Xmx는 최대힙사이즈이다.

 

그렇다면 아무런 설정을 하지 않을 경우 메모리 기본 설정값은 어떻게 될까? 이는 jvm 의 설정을 그대로 따라가는데 물리메모리의 1/64를 초기 힙사이즈로 할당하고 1/4을 최대 힙사이즈로 할당한다.

 

만약 쿠버네티스 환경이라면 pod 이 배포되는 노드의 메모리를 위에서 말하는 물리메모리라고 보면 되면 되는데 Deployment 정의시 컨테이너에 spec.containers[].resources.limits.memory 항목에 최대 메모리를 지정할 경우 해당 용량을 물리메모리로 판단한다.

 

예를 들어 노드의 메모리는 7g 였지만 컨테이너의 spec.containers[].resources.limits.memory 를 512M 로 지정했다면 해당 컨테이너 jvm의 초기 힙사이즈는 512/64=8MB 가 되고 최대 힙사이즈는 512/4=128MB 가 된다.

 

주의할 점은 어플리케이션에서 필요로하는 메모리가 증가할 때마다 최대 힙사이즈까지 점진적으로 힙 사이즈를 늘리게 되는데 이 과정에서 애플리케이션이 일시적으로 멈추는 병목 현상(Stop the World Event)이 발생할 수 있으므로 메모리가 넉넉하다면 처음부터 -Xms 값을 -Xmx와 동일하게 설정하는 방법을 추천하기도 한다.

 

 

또한 64bit 환경에서 물리 메모리가 32GB를 훨씬 초과하는 시스템이라고 하더라도 -Xmx 옵션을 32GB 이하로 설정하는 것이 적절하다. 32GB를 초과하면 힙을 관리하는 방식이 비효율적인 방식으로 변경된다고 한다.

 

참고로 리눅스 환경이라면 물리메모리는 아래 명령어로 확인할 수 있고

cat /proc/meminfo | grep MemTotal

또는 

top

 

할당된 JVM 메모리는 아래 명령어로 확인할 수 있다.

java -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'

(java8 이상 쓰면 permsize 대신 metaspacesize 로)

 

https://jsonobject.tistory.com/382 
http://kkujunhee.net/bbs/board.php?bo_table=os&wr_id=19
https://jang8584.tistory.com/257
728x90