Post

JVM 파라미터

1. 명시적 힙 메모리 –Xms 및 Xmx 옵션

가장 일반적인 성능 관련 사례 중 하나는 애플리케이션 요구 사항에 따라 힙 메모리를 초기화하는 것이다. 그렇기 때문에 최소 및 최대 힙 크기를 지정해야 한다. 이를 달성하기 위해 아래 매개변수를 사용할 수 있다.

1
2
-Xms<heap size>[unit]
-Xmx<heap size>[unit]

여기서 단위는 메모리(힙 크기로 표시)가 초기화되는 단위를 나타낸다. 단위는 GB의 경우 ‘g’, MB의 경우 ‘m’, KB의 경우 ‘k’로 표시할 수 있다 .

예를 들어 JVM에 최소 2GB와 최대 5GB를 할당하려면 다음과 같이 작성해야 한다.

1
-Xms2G -Xmx5G

Java 8부터는 Metaspace의 크기 가 정의되지 않는다. 전역 제한에 도달하면 JVM이 자동으로 증가하지만 불필요한 불안정성을 극복하기 위해 다음을 사용 하여 Metaspace 크기를 설정할 수 있다.

1
-XX:MaxMetaspaceSize=<metaspace size>[unit]

여기서 metaspace size는 Metaspace에 할당하려는 메모리의 양을 나타낸다.

Oracle 지침에 따라 사용 가능한 총 메모리 다음으로 가장 영향력 있는 요소는 Young Generation 용으로 예약된 힙의 비율이다. 기본적으로 YG의 최소 크기는 1310MB이고 최대 크기는 무제한이다.

명시적으로 할당할 수 있다.

1
2
-XX:NewSize=<young size>[unit] 
-XX:MaxNewSize=<young size>[unit]

2. Garbage Collection

애플리케이션의 더 나은 안정성을 위해서는 올바른 가비지 컬렉션 알고리즘을 선택하는 것이 중요하다.

JVM에는 4가지 유형의 GC 구현이 있습니다.

  • 직렬 쓰레기 수집기

  • 병렬 가비지 수집기

  • CMS 가비지 컬렉터

  • G1 가비지 컬렉터

이러한 구현은 아래 매개변수를 사용하여 선언할 수 있다.

1
2
3
4
-XX:+UseSerialGC
-XX:+UseParallelGC
-XX:+USeParNewGC
-XX:+UseG1GC

3. GC 로깅

애플리케이션 상태를 엄격하게 모니터링하려면 항상 JVM의 가비지 컬렉션 성능을 확인해야 한다. 이를 수행하는 가장 쉬운 방법은 GC 활동을 사람이 읽을 수 있는 형식으로 기록하는 것이다.

다음 매개변수를 사용하여 GC 활동을 기록할 수 있다.

1
2
3
4
-XX:+UseGCLogFileRotation 
-XX:NumberOfGCLogFiles=< number of log files > 
-XX:GCLogFileSize=< file size >[ unit ]
-Xloggc:/path/to/gc.log

UseGCLogFileRotation은 log4j, s4lj 등과 같은 로그 파일 롤링 정책을 지정한다. NumberOfGCLogFiles는 단일 애플리케이션 수명 주기 동안 쓸 수 있는 최대 로그 파일 수를 나타낸다.

GCLogFileSize는 파일의 최대 크기를 지정한다. 마지막으로 loggc는 위치를 나타낸다.

여기서 주목해야 할 점은 GC 로그에서 날짜별 타임스탬프를 인쇄하는데 사용할 수 있는 두 가지 JVM 매개변수(-XX:+PrintGCTimeStamps-XX:+PrintGCDateStamps)가 더 있다는 것이다.

예를 들어 최대 100개의 GC 로그 파일을 할당하고 각각의 최대 크기는 50MB이고 /home/user/log/ 위치에 저장하려는 경우 아래 구문을 사용할 수 있다.

1
2
3
4
-XX:+UseGCLogFileRotation  
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=50M 
-Xloggc:/home/user/log/gc.log

그러나 문제는 하나의 추가 데몬 스레드가 항상 백그라운드에서 시스템 시간을 모니터링하는데 사용된다는 것이다. 이 동작은 성능 병목 현상을 일으킬 수 있다. 그렇기 때문에 프로덕션에서는 항상 이 매개변수를 사용하지 않는 것이 좋다.

4. 메모리 부족 처리

큰 응용 프로그램에서 메모리 부족 오류가 발생하여 응용 프로그램 충돌이 발생하는 것은 매우 일반적이다 . 이는 매우 중요한 시나리오이며 문제를 해결하기 위해 복제하기가 매우 어렵다.

이것이 JVM이 힙 메모리를 나중에 누수를 찾는데 사용할 수 있는 실제 파일로 덤프하는 몇 가지 매개변수와 함께 제공되는 이유이다.

1
2
3
4
-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=./java_pid<pid>.hprof
-XX:OnOutOfMemoryError="< cmd args >;< cmd args >" 
-XX:+UseGCOverheadLimit

주의할 몇 가지 사항은 아래와 같다.

  • HeapDumpOnOutOfMemoryError는 OutOfMemoryError의 경우 힙을 실제 파일로 덤프하도록 JVM에 지시한다.

  • HeapDumpPath는 파일이 기록될 경로를 나타낸다. 모든 파일 이름을 지정할 수 있다. 그러나 JVM이 이름에서 <pid> 태그를 찾으면 메모리 부족 오류를 일으키는 현재 프로세스의 프로세스 ID가 .hprof 형식으로 파일 이름에 추가된.

  • OnOutOfMemoryError는 메모리 부족 오류가 발생한 경우 실행할 긴급 명령을 실행하는데 사용된다. cmd 인수 공간에 적절한 명령을 사용해야 한다. 예를 들어 메모리 부족이 발생하는 즉시 서버를 다시 시작하려면 다음 매개변수를 설정할 수 있다.

1
-XX:OnOutOfMemoryError="shutdown -r"
  • UseGCOverheadLimit는 OutOfMemory 오류가 발생하기 전에 GC에서 소비된 VM 시간의 비율을 제한하는 정책이다.

5. 32/64비트

32비트와 64비트 패키지가 모두 설치된 OS 환경에서 JVM은 자동으로 32비트 환경 패키지를 선택한다. 환경을 수동으로 64비트로 설정하려면 아래 매개변수를 사용하여 설정할 수 있다.

1
-d<OS bit>

OS 비트는 32 또는 64 일 수 있다 . 이에 대한 자세한 정보를 찾을 수 있다.

6. 기타

  • -server: “Server Hotspot VM”을 사용하도록 설정한다. 이 매개 변수는 기본적으로 64비트 JVM에서 사용된다.

-XX:+UseStringDeduplication: Java 8u20은 동일한 String의 인스턴스를 너무 많이 생성하여 메모리의 불필요한 사용을 줄이기 위해 이 JVM 매개 변수를 도입했다. 이 매개 변수는 중복된 String 값을 단일 글로벌 char[] 배열로 줄임으로써 힙 메모리를 최적화한다.

-XX:+UseLWPSynchronization: 스레드 기반 동기화 대신 LWP(Light Weight Process) 기반 동기화 정책을 설정한다.

-XX:LargePageSizeInBytes: Java 힙에 사용되는 큰 페이지 크기를 설정한다. 이것은 GB/MB/KB 단위로 인수를 사용한다. 페이지 크기가 클수록 가상 메모리 하드웨어 리소스를 더 잘 사용할 수 있다. 그러나 이는 PermGen을 위한 더 큰 공간 크기를 유발하여 Java 힙 공간의 크기를 강제로 줄일 수 있다.

-XX:MaxHeapFreeRatio: 축소를 방지하기 위해 GC 이후 힙 사용 가능 최대 비율을 설정한다.

-XX:MinHeapFreeRatio: 확장을 방지하기 위해 GC 이후 힙 사용 가능 최소 비율을 설정한다. 힙 사용량을 모니터링하려면 JDK와 함께 제공된 VisualVM을 사용할 수 있다.

-XX:SurvivorRatio: eden/Survivor 공간 크기 비율. 예를 들어 -XX:SurvivorRatio=6은 각 Survivor 공간과 eden 공간의 비율 을 1:6으로 설정한다.

-XX:+UseLargePages: 시스템에서 지원하는 경우 대용량 페이지 메모리를 사용한다. 이 JVM 매개변수를 사용 하면 OpenJDK 7이 충돌하는 경향이 있다.

-XX:+UseStringCache: 문자열 풀에서 사용할 수 있는 일반적으로 할당된 문자열의 캐싱을 활성화한다.

-XX:+UseCompressedStrings:순수한 ASCII 형식으로 표현할 수 있는 String 객체에 byte[] 유형을 사용한다.

-XX:+OptimizeStringConcat: 가능한 경우 문자열 연결 작업을 최적화한다.

[출처 및 참고]

This post is licensed under CC BY 4.0 by the author.