Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

여우발개발

JVM Heap 크기 설정 본문

카테고리 없음

JVM Heap 크기 설정

♬여우 2024. 10. 27. 23:24

Out Of Memory

 운영하는 프로젝트에서 간헐적으로 OOM가 발생했다. Heap dump를 뜨고 살펴봐도 딱히 메모리 누수라던지 특이한 점은 보이지 않았다.

 무언가가 해결되지 않을 때는 돈(과 시간과 노력)이 너무 부족하지는 않았는지 고민해보고, OOM이 딱히 별 이유없이(정말 메모리 누수가 없는 것이 확실한가?) 난 것 같다면 메모리가 너무 부족하지는 않았는지 생각해보자.

 

JVM Memory

out of ‘MEMORY’ 인 건 알겠는데, 어떤 메모리를 추가해야할까?

JVM은 아래같은 구조로 되어있다.

출처 : http://www.libqa.com/wiki/76

 (JAVA 8 이전 기준, Runtime Data Areas 부분을 참고하자)

출처 : https://www.programmersought.com/article/4905216600/#google_vignette

 

여기서 개발자가 new 키워드를 통해 동적으로 생성한 객체들은 Heap Area에 저장되게 된다.

동적으로 생성된 객체들이 Garbage Collector(GC)에 의해 잘 청소되지 않거나, 너무 많이 생성되게 되면 OOM이 발생하게 되는 것이다.

 

JVM Heap

JAVA 8 이후의 JVM Heap 메모리 구조

heap 메모리 사이즈를 설정하지 않으면 기본적으로 운영체제와 RAM 크기에 따라 기본값이 동적으로 결정된다.

InitialHeapSize (=Xms, 최소 힙 크기)

  • JVM은 최소 힙 크기를 작게 설정한 것에서 시작해, 필요에 따라 힙 크기를 점진적으로 늘려간다.
  • 일반적으로 물리적 메모리의 약 1/64 정도가 기본값
    • ex. 8GB의 RAM → 기본값 약 128MB

MaxHeapSize (=Xmx, 최대 힙 크기)

  • JVM이 사용할 수 있는 최대 힙 크기는 물리적 메모리의 일부로 자동 설정된다.
  • 일반적으로 물리적 메모리의 1/4에서 1/2 사이가 기본값
    • ex. 8GB RAM → 약 2GB 또는 4GB

 

기본값은 애플리케이션에 맞지 않거나 성능에 최적화되지 않을 수 있기 때문에, 메모리 요구 사항에 맞게 명시적으로 설정하는 것이 좋다.

 

최소 힙 크기 < 최대 힙 크기

heap 크기가 다 차게 되면 heap 크기를 점진적으로(최대 Xmx만큼) 늘리게 되는데, 이 때 GC가 발생하게 된다. GC가 동작할 때는 다른 쓰레드는 멈추고 GC의 쓰레드만 동작하게 되어 성능적으로 문제가 될 수 있다 (Stop the world).

⇒ 최소 힙 크기 = 최대 힙 크기로 지정하는 것이 좋다.

최대 힙 크기가 너무 적으면

가용할 수 있는 heap Area가 너무 적어 위에서 이야기했던 OOM이 자주 발생하게 된다. 그러니 적당한 heap 크기를 설정해 주는 것이 자바 어플리케이션 성능에 큰 영향을 미치는 것은 당연지사.

그래서 어떻게 설정해야 하죠?

…하지만 언제나 ‘적당한’ 이라는 단어는 너무 어렵다. 도대체 어느 정도가 적당한가. 물론 어플리케이션마다 모니터링을 하면서 봐야겠지만 아무런 데이터가 없는 첫 상태에서는?

관리형 서비스를 제공하는 기업들의 사례를 참고해서 설정해보자.

  1. Oracle EPM System

https://docs.oracle.com/applications/help/ko/enterprise-performance-management/11.2/HITDO/optimizing_performance_by_changing_the_heap_size.htmhttps://docs.oracle.com/applications/help/ko/enterprise-performance-management/11.2/HITDO/optimizing_performance_by_changing_the_heap_size.htm

기본적으로 Java 웹 애플리케이션을 단일 관리 서버에 배포하는 경우 EPM System Configurator는 머신의 메모리를 기반으로 단일 관리 서버의 기본 힙 크기를 설정합니다.

  • 머신의 메모리가 12GB 이상인 경우 힙 크기를 8GB로 설정
  • 6GB 이상 12GB 미만인 경우 힙 크기를 4GB로 설정
  • 32비트 머신에서 6GB 미만인 경우 힙 크기를 750MB로 설정
  • 64비트 머신에서 6GB 미만인 경우 힙 크기를 1,536MB로 설정
  1. Azure Spring Apps

https://learn.microsoft.com/ko-kr/azure/spring-apps/basic-standard/concepts-for-java-memory-management

Azure Spring Apps는 기본 최대 힙 메모리 크기를 Java 앱용 앱 메모리의 약 50%-80%로 설정합니다.

  • 앱 메모리 <가 1GB인 경우 기본 최대 힙 크기는 앱 메모리의 50%입니다.
  • 1GB <= 앱 메모리 < 2GB인 경우 기본 최대 힙 크기는 앱 메모리의 60%입니다.
  • 2GB <= 앱 메모리 < 3GB인 경우 기본 최대 힙 크기는 앱 메모리의 70%입니다.
  • 3GB <= 앱 메모리인 경우 기본 최대 힙 크기는 앱 메모리의 80%입니다.

 

 

OOM이 났던 우리 서버는 설정을 한 것 처럼 보였지만 실제 적용이 되지 않아서 heap 크기가 디폴트로 설정되어있는 상태였다! 설정 후에 모니터링까지 해서 제대로 설정이 되었는지까지 꼭꼭 확인하도록 하자.