JVM 성능 조절 필요성
한개의 서버를 여래개의 가상서버로 분할하여 사용하고 있어 메모리 사용량이 100% 가까이 올라갈 수 있다
메모리 관련 옵션의 의미를 정리하고 메모리 사용 구조에 대한 이해를 기반으로 추후 메모리 최적화 지식이 필요
이클립스 뿐만 아니라 JVM을 사용하는 모든 Java 어플리케이션은 -vmargs 옵션에 따라 성능이 좌우되며, 필요한 경우에는 적당한 설정이 필요
JVM 동작방식
《힙 크기에 관한 JVM이 부여하는 디폴트》
- 물리 메모리의 1/6 크기 최소 힙 크기(-Xms)
- 물리 메모리의 1/4 크기 최대 힙 크기(-Xmx) 할당
- (ex) 물리 메모리가 32GB 가정 시, -Xms4G, -Xmx8G 할당
JVM :
애플리케이션 시작시 -Xms로 설정한 값으로 힙 크기 생성
요구량 증가할 때마다 -Xmx로 설정한 값까지 점진적으로 힙 크기 증가
힙 크기를 늘리는 과정에서 애플리케이션이 일시 정지하는 병목 현상(Stop the World Event)발생
물리 메모리가 넉넉하다면 초기 -Xms , -Xmx 값을 동일하게 설정하기 추천
64-bit 환경 상 물리 메모리가 32GB 초과 시스템이라도 -Xmx 옵션은 32GB 이하 설정이 적절
32GB 초과 시, 힙 관리 방식이 비효율적 방식으로 변경
XX:MaxMetaspaceSize
- Permanent Generation 영역
- (과거) -XX:MaxPermSize 가 Java 8부터 명칭 변경
- 디폴트 64MB가 사용되며 일반 엔터프라이즈 용도로는 낮은 수치. 오라클은 256MB 설정 권장
- Heap = Edn + Survivor + Old
- Non-Heap = Perm ( 또는 스택, 클래스 area, method area 등의 heap영역 제외)
- permanent : Class 메타정보, Method 메타정보, Static Object, 상수화된 String Object, Calss관련 배열 메타정보, JVM내부 객체와 최적화컴파일러(JIT)최적화 정보 등 포함
JVM 파라미터 옵션 표기 방법 및 종류
JVM Option 은 -X로 시작하는 것, -XX로 시작하는 것이 있다.
(1) -X
- 비표준. 모든 JVM에서 지원하는 것은 아님
- 특별 공지없이 변경 가능
(2) -XX
- 안정버전은 아님 .일반적 권장 안함
-XX:[+|-]<option> 방식
기능을 키거나(+)/끄기(-)
-XX:<option>=<string> 처럼 특정값 지정
(3) Boolean JVM 옵션
- -XX:+PrintGCDetails
(4) Numeric JVM 옵션
- m,M 또는 k,K를 사용 가능
- -Xms1024m
(5) String JVM 옵션
- 파일, 경로, 커맨드 지정
- -Dfile.encoding=UTF-8
→ (리눅스 서버) java -help는 표준옵션 또는 java -X로 비표준 옵션 확인 가능
JVM Option
JVM Config 예시
《Java < 8 》
-server -Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k] -XX:PermSize=<perm gen size>[g|m|k] -XX:MaxPermSize=<perm gen size>[g|m|k] -Xmn<young size>[g|m|k] -XX:SurvivorRatio=<ratio> -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent> -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>" -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Dsun.net.inetaddr.ttl=<TTL in seconds> -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof -Djava.rmi.server.hostname=<external IP> -Dcom.sun.management.jmxremote.port=<port> -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
《Java ≥ 8》
-server -Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k] -XX:MaxMetaspaceSize=<metaspace size>[g|m|k] -Xmn<young size>[g|m|k] -XX:SurvivorRatio=<ratio> -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent> -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>" -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Dsun.net.inetaddr.ttl=<TTL in seconds> -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof -Djava.rmi.server.hostname=<external IP> -Dcom.sun.management.jmxremote.port=<port> -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
JVM Option 조절 상황
(1) Hot Deploy 사용으로 재배포가 자주 일어나는 시스템 환경인 경우
- PermGen 영역의 사이즈를 충분히 늘린다. (but 한계 존재)
- UseConcMarkWeepGC, CMSPermGenSweepingEnabled, CMSClassUnloadingEnabled 등의 옵션으로 PermGen영역도 GC 수행
(2) OOME, PermGen OOME 발생
- OOME : Xms, Xmx 조정
- PermGen OOME : XX:PermSize, XX:MaxPermSize 조정
(cf) OS에서 Xms, Xmx를 동일하게 세팅하는 이유
- Xms로 init 메모리를 잡고, committed 도달할 때까지 Used용량은 점차 증가한다.
- committed 도달한 경우, 메모리 추가할당시 시스템 부하발생 (WAS가 몇 ms가량 정지 가능성)
- 메모리 용량은 init < used < committed < max
⇒ init와 max사이에서 used 메모리가 committed까지 사용하게 되면, 신규 메모리 공간을 요구하는데, 약 1초가량 jvm이 메모리 할당 중 정지한다. Xms와 Xmx를 동일하게 셋팅하여 메모리를 확보한 상태에서 jvm 기동한다.
Heap 사이즈 관련 옵션
-Xms : 자바 초기 heap 사이즈
-Xmx : 자바 최고 heap 사이즈
-Xss : 자바 thread stack 사이즈
GC log 관련 옵션
(1) -verbose:gc → GC 수행소요시간 파악 툴
GC가 문제인지 확인
(ex)
GC 39709K→25117K(83008K) 0.00002342(sec)
(2) -XX:+PrintGCDetails : new영역의 크기 및 시간 정보
(3) XX:-PrintGCTimeStamps : GC 발생시 타임 스탬드
→ 2,3 둘다 기입하여 GC 성능 튜닝에 참고한다.
특정 GC위한 옵션
-XX : UseparalellGC
-XX : UseConcMarkSweepGC (1.4 이후)
-XX : USerial GC (1.5 이후)
원격 디버깅을 위한 JVM 옵션
-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
프로파일링을 위한 JVM 옵션
-Xprof
-Xrunhprof
클래스패스와 관련된 JVM 옵션
-Xbootclasspath : Verification 없이 로드되도록 classpath 설정
-Xbootclasspath/a : 부트스트랩 클래스 앞에 위치하도록 설정
-Xbootclasspath/p : 부트스트랩 클래스 뒤에 위치하도록 설정
- JVM은 로드되는 모든 클래스에 대해 검증작업 진행 → JVM 안정성 기여
- costly 하므로 JVM 구동 시 지연의 원인이 된다
- 해당 설정으로 검증작업 없이 빠른 로드는 가능하나 신중할 필요
Perm Gen Size 관련 옵션
-XX:PermSize
-XX:MaxPermSize=64m : Permanent Generation 사이즈 설정
-XX:NewRatio=2 : new 와 old 영역 비율
→ java.lang.OutOfMemoryError:Perm Gen Space 문제 연관
클래스 로딩/언로딩 Trace 관련 옵션
-XX:+TraceClassLoading
-XX:+TraceClassUnloading
- 클래스가 JVM에 로드/언로드 될 때 로그를 기록
- 메모리릭, 의심가는 클래스의 로딩/언로딩을 확인하기
- 오래된 클래스가 실제 GC가 되는지 확인하기
로깅 관련 JVM 옵션
-XX:+PrintCompilation
- 어떤 메소드가 JIT compiler에 의해 컴파일 되는지 기록
디버깅 관련 옵션
-XX:HeapDumpPath=./java_pid.hprof : heap dump 경로 지정
-XX:PrintConcurrentLocks : Ctrl-Break thread dump 시, lock 정보를 뿌려준다
-XX:PrintCommandLineFlags : 시작시 command line 찍어줌
이클립스에서 Heap 사이즈 늘리기
자바는 힙메모리를 사용하며, 힙메모리 설정에 따라 어플리케이션 성능이 상당부분 좌우된다.
※ 힙메모리 역할
- new 연산자로 생성된 객체와 배열을 저장하는 공간
- 클래스 영역에 로드된 클래스만 생성가능
- Garbage Collector를 통해 메모리 반환
이클립스 성능 최적화 작업
《 JVM으로부터의 이클립스 메모리 할당 》
- 이클립스는 JVM을 통해서 메모리를 할당받으므로, 8GB 이상의 컴퓨터 환경이라도 이클립스 입장에서는 메모리 부족현상 발생 가능
- 이클립스 실행시 옵션은 크게 [platform options]과 [-vmargs]로 나누고 있음
- 이클립스 설치 디렉토리에 있는 eclipse.ini 파일 확인
- → JVM 옵션 설정 관련 부분 : vmargs (virtual machine arguments) 항목
-startup plugins/org.eclipse.equinox.launcher_1.1.0.v20100507.jar --launcher.library plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.0.v20100503 -product org.eclipse.epp.package.jee.product --launcher.defaultAction openFile --launcher.XXMaxPermSize 256M -showsplash org.eclipse.platform --launcher.XXMaxPermSize 256m --launcher.defaultAction openFile -vmargs -Dosgi.requiredJavaVersion=1.5 -Xms40m -Xmx512m
(1) eclipse/eclipse.ini 파일 설정 변경하기
힙 메모리 설정
(ex) Xms1024m -Xmx2048m 등 로컬 환경에 맞게 조절
Xverify:none → 이클립스 빠른 구동 관련 설정
(2) GC 설정
XX:+UseG1GC
(3) 이클립스 Tomcat JVM 옵션 조정
① Servers > Tomcat > open launch configuration
VM arguments : Xms1024m -Xmx2014m -XX:+UseG1GC -XX:MaxPermSize=512m 추가
또는
② 프로젝트 > properties > Run/Debug Settings
Arguments탭에서 VM arguments 란에 원하는 heap size를 추가
Xms1024m -Xmx2048m
(4) 이클립스에서 힙 메모리 상태 체크
Windows->Preferences->General->show heap status"항목에 체크박스를 활성화하고 OK
⇒ 이클립스 오른쪽 하단에 메모리가 동작되는 것이 보이는데 휴지통을 클릭하면 GC (Garbage Collection)를 강제 실행
totalMemory() 사용으로 JVM heap size 구하기
public class HeapSize{ public static void main(String[] args){ // get the jvm heap size long heapSize = Runtime.getRuntime().totalMemory(); System.out.println("Heap Size : " + heapSize); System.out.println("Heap Size(M) : " + heapSize / (1024 * 1024) + " MB"); } }
JVM 구동시 옵션을 주면, Heap Size를 늘릴 수 있다.
참고블로그
https://jsonobject.tistory.com/382
http://wiki.gurubee.net/pages/viewpage.action?pageId=34603019
https://cornswrold.tistory.com/206
https://javaslave.tistory.com/23
https://gblee1987.tistory.com/29
https://waspro.tistory.com/340
https://lky1001.tistory.com/169
아직 볼것
'[Development] > DailyGoogle' 카테고리의 다른 글
【D.D.S JAVA】Java 메모리 구조 (JVM) 및 런타임 메모리 구조 (0) | 2021.04.20 |
---|---|
【D.D.S :: OS】Java 애플리케이션 OOME(Out Of Memory Error) (0) | 2021.04.19 |
[##190526##] 환경변수의 의미 및 설정 목적 (0) | 2019.05.26 |