Skip to content

자바 프로세스 힙메모리 설정 이슈

자바 프로세스 힙메모리 설정 이슈
목차




서론

OOM Killer에 의해 자바 프로세스가 예기치 않게 다운되는 현상이 발생하였습니다.

메모리 바운더리 설정을 하지 않은 자바 프로세스가 리눅스 OOM Killer에 의해 다운되었다고 생각했으나, 분명 해당 자바 프로세스는 메모리 설정이 되어있는 상태였습니다.

자바 프로세스에 -Xms, -Xmx 옵션을 통해 힙메모리를 부여하였으나, 여전히 프로세스 다운현상이 발생하였고, 프로세스의 메모리를 확인해 보았을때, 부여한 옵션값과는 다르게 적용된 것처럼 보이는 현상이 발생하였습니다.

회사의 다른 자바 프로세스들의 힙메모리를 확인해봐도 제가 생각한 -Xms, -Xmx 옵션을 통한 메모리 바운더리와 실제 메모리 바운더리가 일치하지 않았습니다.

자바 프로세스의 힙메모리 설정에 대한 의문이 생기게 되었고, 왜 예상과 달리 동작하는지 확인해보았습니다.





의문점

  1. 실제 -Xms 로 할당한 최소힙메모리보다 사용중인 실제 메모리가 작은 이유??

  2. -Xms300m을 잡아도 free -h 로 확인해보니 할당된 메모리는 100m??

  3. -Xmx로 할당한 최대힙메모리가 실제로 적용되고 있는가??

  4. jdk8버전 이후부터 바뀐 메모리구조로 인해 어떠한 설정을 추가적으로 해야 하는가?




확인결과

1. 실제 -Xms 로 할당한 최소 힙메모리보다 사용중인 실제 메모리가 작은 이유??

  • free -h , 혹은 htop(res) 을 통해 확인하는 메모리는 프로세스의 물리적인 메모리.

  • 자바옵션으로 주어지는 힙메모리(-Xms, -Xmx)는 가상메모리를 할당하는 것.

  • 실제로 객체가 생성되어 힙에 올라가기 전까지 물리메모리가 증가하지는 않음.

    a. -Xms2g, -Xmx2g일 경우의 가상메모리는 총 4224m으로 잡혀있음(힙메모리+Native 메모리) JVM 힙메모리 -Xms2g -Xmx2g 설정 시 가상메모리 측정값



    b. -Xms1g, -Xmx1g일 경우의 가상메모리는 총 3148m으로 잡혀있음(힙메모리+Native 메모리) JVM 힙메모리 -Xms1g -Xmx1g 설정 시 가상메모리 측정값




2. -Xmx로 할당한 최대힙메모리가 실제로 적용되고 있는가??

최대힙메모리는 4g가 주어져 있는 상황. 실제로 4g가 할당되어 있을까?

jstat 명령어를 통해 gc가 이루어지고 있는 메모리 region들의 할당크기와 사용량을 확인해보면,

4096 + 718848 + 347136 = 4,194,304 KByte = 4 GByte, 정확하게 4G가 나온다. 잘적용되고있음.

JVM Native 메모리 영역 상세 구성


3. JDK8 이 후 바뀐 메모리구조로 인해 어떠한 설정을 추가적으로 해야 하는가?

JDK 8에서 클래스 메타데이터 저장 공간은 PermGen에서 네이티브 메모리의 Metaspace로 이동했습니다. Java heap의 Old 영역과는 별개입니다. MaxMetaspaceSize를 지정하지 않았다고 Old 영역이 그 때문에 차거나 minor GC가 반복된다고 설명할 수는 없습니다.

MetaspaceSize는 메타데이터 사용량에 따른 GC 유발 임계값의 초기값이고, MaxMetaspaceSize는 상한입니다. 상한 도달만이 클래스 언로딩 조건은 아닙니다. 클래스 로더의 도달 가능성과 GC 구현·설정을 함께 봐야 합니다. 상한을 과하게 낮추면 오히려 OutOfMemoryError: Metaspace가 발생할 수 있습니다.

이 장애에서 힙 상한만으로 프로세스 전체 메모리를 제한할 수 없다는 교훈은 유효합니다. 다만 Metaspace 누수가 직접 원인이었다고 확정하려면 Native Memory Tracking, 클래스 로더 수, GC 로그와 OS의 OOM 기록이 필요합니다. Oracle Java 메모리 문제 진단 문서를 참고할 수 있습니다.





결론

  • 컨테이너·OS 메모리 한도 안에 Java heap, Metaspace, 스레드 스택, 직접 버퍼, 코드 캐시 및 기타 네이티브 메모리를 함께 예산으로 잡아야 합니다. Xmx와 MaxMetaspaceSize만으로 OOM Killer를 막을 수 있다고 보장할 수는 없습니다.

  • 힙메모리가 크다고 무조건 좋은게 아니다.

  • 힙메모리가 클수록 fullGC 속도가 느림. → 대용량 건에 안전/유리 → batch 서비스

  • 힙메모리가 작을수록 fullGC 속도가 빠름. → 응답 반응성에 유리 → api 서비스

  • trade-off가 발생, 적당히 선택할 것.

참고 :

https://brunch.co.kr/@heracul/1



읽어주셔서 감사합니다.🖐


Ramsbaby
Written byRamsbaby
이 블로그는 직접 개발/운영하는 블로그이므로 당신을 불쾌하게 만드는 불필요한 광고가 없습니다.

#My Github#소개 페이지#Blog OpenSource Github