JVM 메모리 구조와 JAVA OPTION 값 정리

WAS상에서 JAVA 기반 어플리케이션을 구동시키다 보면 OOM 관련 에러를 심심치 않게 볼 수 있다. 특히나 현재 수행하고 있는 PJT는 한개의 서버를 여래개의 가상서버로 분할하여 사용하고 있어 메모리 사용량이 심심치 않게 100% 가까이 올라가곤 한다. 그래서 메모리 최적화 까지는 아니더라도, 메모리 관련 옵션이 어떤 의미인지 정리해두고 조금이나마 메모리 사용 구조에 대한 이해를 하고자 했다.




JVM 메모리 구조

  • Heap = Edn + Survivor + Old

  • Non-Heap = Perm 이다. 

메모리는 우선, Heap과 Non-Heap 으로 나뉜다. 상세 역할과 구분은 아래를 참고 하자.


CG와 Heap영역의 기본 동작원리 : 

cg는 Eden과 ss1을 클리어 (살아있는 녀석은 ss2로 피신),

그 다음 cg는 Eden과 ss2를 클리어 (살아있는 녀석은 ss1으로 피신) 시키는 방법으로 동작한다.

  • Heap영역 : new 연산자로 생성된 객체와 배열을 저장하는 영역으로 GC 대상이 되는 영역이다.

Eden : new 키워드를 통해서 객체가 처음 생성되는 공간

Survivor : CG가 수행될 때 살아있는 객체는 survivor영역으로 이동된다. (임시피난소)

Old : survivor에서 일정시간 참조되는 객체들이 이동되는 공간

  • Non-Heap영역 : 스택, 클래스 area, method area 등의 heap영역을 제외한 녀석들

Permanent : Class 메타정보, Method 메타정보, Static Object, 상수화된 String Object, Calss관련 배열 메타정보, JVM내부 객체와 최적화컴파일러(JIT)최적화 정보 등 포함


XX:MaxPermSize 옵셥 값 : 

그래서 XX:MaxPermSize 옵션으로 지정하고 hot-deploy가 있을 때 메모리 사용량이 점차 증가하는 부분이다. 가령 서버에서 PermGen OOM 에러가 발생 시 이부분의 사이즈를 조절해야 한다.



JVM Option 정리

 - Xms

 초기 Heap Size (init, default 64m)

 -Xmx

 최대 Heap Size (Max,  default 256m)

 -XX:PermSize

 초기 PermSize 

 -XX:MaxPermSize

 최대 PermSize 

 -XX:NewSize

 최소 new size (객체가 생성되어 저장되는 초기공간의 Size로 Eden+Survivor 영역)

 -XX:MaxNewSize

 최대 new Size 

 -XX:SurvivorRatio

 New/Survivor영역 비율 (n으로 지정시 Eden : Survivor = 1:n) 

 -XX:NewRatio

 Young Gen과 Old Gen의 비율 (n으로 지정시 Young : Old = 1:n) 

 -XX:+DisableExplicitGC

 System.gc() 콜을 무시 

 -XX:+UseConcMarkWeepGC

 표준 gc가 아니나 Perm Gen영역도 gc하는 Concurrent Collertor를 사용

 - XX:+CMSPermGenSweepingEnabled

 Perm gen영역도 GC의 대상이 되도록 지정 

 - XX:+CMSClassUnloadingEnabled 

 클래스 데이터도 GC의 대상이 되도록 지정


위에 기본 값을 기준으로 흰하게 일어나는 상황에 대한 조치방법을 간략하게 정리.


  • Hot Deploy 사용으로 재배포가 자주 일어나는 시스템 환경인 경우
  1. PermGen 영역의 사이즈를 충분히 늘린다. (but 한계 존재) 
  2. UseConcMarkWeepGC, CMSPermGenSweepingEnabled, CMSClassUnloadingEnabled 등의 옵션으로 PermGen영역도 GC 수행


  • OOME, PermGen OOME 발생
  1. OOME : Xms, Xmx 조정
  2. PermGen OOME : XX:PermSize, XX:MaxPermSize 조정


  • Xms, Xmx를 동일하게 세팅하는 이유
  1. Xms로 init 메모리를 잡고, committed 도달할 때까지 Used용량이 점차 증가하는데, committed에 도달시 메모리 추가할당시 시스템 부하발생 (WAS가 몇 ms가량 멈출 가능성 있음)
  2. 메모리 용량은 init < used < committed < max 

추가 정리 : 

보통 운영시스템에서 Xms와 Xmx를 동일하게 지정하는 이유는 init와 max사이에서 used 메모리가 committed까지 사용하게 되면, 신규 메모리 공간을 요구하는데 이 때 약 1초가량 jvm이 메모리 할당 중 멈춰버리는 경우가 있다. 그래서 Xms와 Xmx를 동일하게 주고 메모리를 확보한 상태에서 jvm을 기동시키곤 한다. 



참고사이트

http://d2.naver.com/helloworld/1329

http://d2.naver.com/helloworld/184615

http://d2.naver.com/helloworld/37111


첨부파일 존재

 

HP JVM 튜닝 옵션.pdf

 

JVM GC 과 JVM GC 과메모리 Tuning Tuning .pdf

 

OutOfMemory.pdf

 

SUN JVM 튜닝 옵션.pdf

 

jvm 메모리구조.pdf


이 글을 공유하기

댓글

Email by JB FACTORY