레거시 코드를 분석하다보니 SpringBoot 로 구성된 자바 서버 구동시 몇가지 JVM 옵션을 지정하고 있어서 확인해봤다. 뭐든 확실하지 않은 건 안 쓰느니만 못하니까.
참고로 Tomcat 에서는 JVM 옵션을 JAVA_OPTS와 GC_OPTS 라는 환경변수 값으로 나눠서 지정하기 때문에 그 기준으로 작성하였다. 추가로 확인된 사항은 수시로 업데이트 할 예정.
JAVA_OPTS: -server
Server HotSpot JVM을 사용하는 옵션이다. Server HotSpot JVM은 Desktop용 Appkication을 구동하는데 유리하고, 최적화(Optimization)에 필요한 모든 과정을 최대한으로 수행한다. Application의 시작시간은 느리지만, 일정 시간이 흐르면 Client HotSpot JVM에 비해 훨씬 뛰어난 성능을 보장한다.
단, jdk 1.5부터는 2개 이상의 CPU와 2G 이상의 메모리를 갖춘 머신을 Server-Class 머신으로 분류하여 그 경우 -server 옵션이 기본값이다.
JAVA_OPTS: -Djava.security.egd=file:/dev/./urandom
톰캣은 자바의 SecureRandom 클래스를 사용해서 세션 아이디 같은 것을 생성한다. 리눅스(linux) 환경의 경우 /dev/random 또는 /dev/urandom 라는 난수생성기 제공하는데 SecureRandom 클래스는 기본적으로 /dev/random 사용한다.
난수 발생기는 디바이스 드라버에서 발생하는 입력 신호 등을 이용해서 난수를 생성한다. 즉, 키보드나 마우스 클릭 같은 디바이스의 입줄력 신호를 엔트로피 풀(Entropy pool)에 저장하고 난수를 생성할때 엔트로피 풀에서 필요한 크기 만큼 가져다 사용하게 된다.
그런데 /dev/random 경우 엔트로피 풀에 필요한 크기 만큼의 데이터가 부족할 경우 블록킹(blocking) 상태로 대기하게 된다. 이런 경우 애플리케이션이 행(hang)에 걸린것 처럼 멈처버리는 현상이 발생한다.
하지만 /dev/urandom 은 /dev/random에 비해서는 난수의 무작위성이 떨어지지만 엔트로피 풀에 있는 데이터가 충분하지 않아도 난수를 생성해 버린다.
이런 이유로 난수로 인한 애플리케이션의 블록킹 사태를 막기 위해 위와 같은 옵션을 주어 /dev/urandom를 사용하기도 한다.
JAVA_OPTS: -Xms8g -Xmx8g
Heap 사이즈 최소크기와 최대크기를 지정한다. 애플리케이션 시작시 -Xms로 설정한 값으로 힙 크기를 생성하고 요구량이 증가할 때마다 -Xmx로 설정한 값까지 점진적으로 힙 크기를 늘린다.
만약 해당 설정을 수동으로 하지 않을 경우 JVM은 물리 메모리의 1/6 크기를 최소 힙 크기(-Xms)에, 물리 메모리의 1/4 크기를 최대 힙 크기(-Xmx)에 할당한다. 물리 메모리가 32GB라고 가정하면 -Xms4g, -Xmx8g 정도를 할당하는 셈이다.
힙 크기를 늘리는 과정에서 애플리케이션이 일시적으로 멈추는 병목 현상(Stop the World Event)이 발생할 수 있기 때문에 물리 메모리가 넉넉하다면 처음부터 -Xms 값을 -Xmx와 동일하게 설정하는 방법을 추천하기도 한다.
GC_OPTS: -XX:+UseG1GC
Parallel GC 보다 전체적인 처리량이 줄어들지만 GC로 인한 일시 정지 시간을 크게 단축한다. Java 9부터 디폴트 GC이다.
https://gampol.tistory.com/entry/Tomcat-구동-시-devurandom-블로킹-이슈지연시작-문제
https://www.kangwoo.kr/2018/02/06/spring-boot-시작시-dev-urandom을-사용하는-이유/
https://www.baeldung.com/java-security-egd
https://johngrib.github.io/wiki/jvm-memory/
https://johngrib.github.io/wiki/java-g1gc/
https://jsonobject.tistory.com/382
https://sftth.github.io/java/java-jvmoption/
https://cheezred.tistory.com/154
'Backend > Java' 카테고리의 다른 글
flatMap (0) | 2022.09.07 |
---|---|
@JsonCreator (0) | 2021.11.19 |
AutoBoxing과 AutoUnBoxing (0) | 2021.08.25 |
@Async, CompletableFuture, parallelStream (0) | 2021.07.14 |
Collections.EMPTY_LIST, Collections.EMPTY_MAP (0) | 2021.07.12 |