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 사용으로 재배포가 자주 일어나는 시스템 환경인 경우
- PermGen 영역의 사이즈를 충분히 늘린다. (but 한계 존재)
- UseConcMarkWeepGC, CMSPermGenSweepingEnabled, CMSClassUnloadingEnabled 등의 옵션으로 PermGen영역도 GC 수행
- OOME, PermGen OOME 발생
- OOME : Xms, Xmx 조정
- PermGen OOME : XX:PermSize, XX:MaxPermSize 조정
- Xms, Xmx를 동일하게 세팅하는 이유
- Xms로 init 메모리를 잡고, committed 도달할 때까지 Used용량이 점차 증가하는데, committed에 도달시 메모리 추가할당시 시스템 부하발생 (WAS가 몇 ms가량 멈출 가능성 있음)
- 메모리 용량은 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
첨부파일 존재
JVM GC 과 JVM GC 과메모리 Tuning Tuning .pdf
출처: http://javaslave.tistory.com/23 [전산쟁이]
'SERVER > TOMCAT' 카테고리의 다른 글
톰캣 설치 (0) | 2017.12.06 |
---|---|
톰캣 튜닝 (0) | 2017.12.06 |
TOMCAT 서버 여러개 컨테이너 셋팅하기 (0) | 2017.10.17 |
톰캣 서버 설정 참조 (0) | 2017.01.16 |
64비트 데이터모델을 써보자 (0) | 2016.01.26 |
Apache Tomcat reload (java 파일 변경 내역 자동반영) (0) | 2015.11.03 |
Tomcat 7 에서 web.xml에 사라졌다. (0) | 2015.04.07 |
[OS][LINUX][apache][tomcat]was/web 연동 (0) | 2014.05.13 |