본문 바로가기
[Development]/DailyGoogle

【D.D.S :: JAVA】JVM Option

by Inkim 2021. 4. 21.

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

행동옵션

성능옵션

GC옵션

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 사용으로 재배포가 자주 일어나는 시스템 환경인 경우

  1. PermGen 영역의 사이즈를 충분히 늘린다. (but 한계 존재)
  2. UseConcMarkWeepGC, CMSPermGenSweepingEnabled, CMSClassUnloadingEnabled 등의 옵션으로 PermGen영역도 GC 수행

(2) OOME, PermGen OOME 발생

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

(cf) OS에서 Xms, Xmx를 동일하게 세팅하는 이유

  1. Xms로 init 메모리를 잡고, committed 도달할 때까지 Used용량은 점차 증가한다.
  2. committed 도달한 경우, 메모리 추가할당시 시스템 부하발생 (WAS가 몇 ms가량 정지 가능성)
  3. 메모리 용량은 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://m.blog.naver.com/PostView.nhn?blogId=youreme&logNo=110158875473&proxyReferer=https:%2F%2Fwww.google.com%2F

https://lky1001.tistory.com/169

https://m.blog.naver.com/PostView.nhn?blogId=weekamp&logNo=220946456496&proxyReferer=https:%2F%2Fwww.google.com%2F

아직 볼것

https://linuxism.ustd.ip.or.kr/236