Skip to content

Latest commit

 

History

History
248 lines (159 loc) · 15.8 KB

java-gc.adoc

File metadata and controls

248 lines (159 loc) · 15.8 KB

default GC 찾기 : java -XX:+PrintCommandLineFlags -version

영역 구분

  • Young Generation

    • eden

    • survivor1

    • survivor2*

  • Old Generation

    • Tenured* Method area

  • Pergem

  • Minor GC : Young의 Eden에 객체가 최초로 할당되는데, 객체가 계속 할당되면 참조되는 객체(Live Object)들은 Survivor1이나 Survivor2로 옮겨지고, 더 이상 참조되지 않는 객체들은 삭제됩니다.

  • Full GC 혹은 Major GC : Minor GC의 결과로 충분히 오랫동안 참조된 객체들은 Old로 승격(Promotion) . Old의 메모리가 충분하지 않으면 Old에서 더 이상 참조되지 않는 객체를 삭제해서 공간을 확보해야 함.

Garbarge Collector 방식

  • Parallel Collector : (Throughput) 위주

  • CMS : 응답시간 개선(Low Pause) 위주

Serial GC

Pararrel GC

스레드의 작업을 멈춘 후에는 모든 CPU들이 협력하여 GC를 수행.이 옵션을 사용할 경우에는 CPU는 적게 소모하지만, Full GC를 수행할 때 많은 시간이 소요되는 문제가 발생함.

Pararrel Old GC(Parral Compacting GC)

Concurrent Mark And Sweep

작업스레드와 병행하여 GC관련 정보를 수집해 둠. 특정 CPU를 GC를 위해 할당한 후에 사용중인 객체를 프로그램 수행과 동시에 파악함  지속적으로 GC를 위한 작업을 수행하므로 CPU는 더 많이 사용하지만, Full GC 시간이 줄어드는 장점이 있음. 일명 Low latency GC. 그러나 Concurrent mode failure가 발생하면 다른 Parallel GC보다 느리다.
  • -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseConcMarkSweepGC

  • -XX:+UseParNewGC : CMS Collector를 사용하는 경우에 한해서, Young에 대해서 Parallel Collection을 수행할 지의 여부를 지정함

  • -XX:+CMSParallelRemarkEnabled : -XX:+UseParNewGC와 같이 사용할 때 Remark Phase의 Pause Time을 좀 더 줄이기 위해서 사용하는 옵션임

  • -XX:+UseConcMarkSweepGC : CMS Collector를 사용할 지의 여부를 지정함

-XX:PermSize=256m -XX:MaxPermSize=256m -Xms1024m -Xmx1024m -server -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseConcMarkSweepGC

  • Promotion Failure : Promotion Failure는 New의 객체가 Old로 승격될 때 Old에 할당 가능한 공간이 없는 현상.

  • Concurrent Mode Failure : GC 작업이 수행되는 중에 New의 객체가 Old로 승격되면서 Old에 할당 가능한 공간이 없는 현상. 이때는 강제로 Stop The World GC를 수행해서 공간을 확보함.

CMS gc의 시작 타이밍 더 빠르게하기

cms full gc (concurrent mode fail, promotion fail) 를 개선하기 위해서 cms gc가 시작되는 메모리 사용량은 90%가 기본값. 더 적은 한계값을 적용

-XX:CMSInitiatingOccupancyFraction=N -XX:+UseCMSInitiatingOccupancyOnly

N 70으로 주면 70%정도 old gen이 찾을 경우 cms gc를 시작. 더 많은 가용공간을 확보된 상황에서 gc를 하기 때문에 promotion fail이 잘 발생하지 않음. - promoation fail은 old 영역의 단편화로 인한 현상이므로 충분한 메모리가 확보된 상황이라면 확률을 줄일 수 있음.

CMS Collector는 Permanent Generation(이하 Permanent)에 대해 GC 작업과 Class 메타데이터에 대한 Unloading 작업을 수행하지 않음. 따라서 Application의 특성상 많은 수의 Class를 동적으로 생성하고 Loading하는 경우에는 Permanent 에서 OOM(Out Of Memory) 에러가 발생할 수 있음. Permanent 조절 필요성 검토

-XX:PermSize=256m -XX:MaxPermSize=256m

RMI full gc

-XX:+CMSParallelRemarkEnabled -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=60 - XX:+UseCMSInitiatingOccupancyOnly으로 설정해도 RMI때 Full GC

아래 설정으로 주기 조정가능

-Dsun.rmi.dgc.server.gcInterval=VALUE-Dsun.rmi.dgc.client.gcInterval=VALUE

아래 옵션 붙이면 Full GC대신 CMS GC-XX:+ExplicitGCInvokesConcurrent

-XX:+CMSClassUnloadingEnabled을 적용한다.

이 경우, Minor GC마다 Perm Gen 영역을 GC하므로 Unloading되어야 할 Class가 잡고 있는 Old Gen 영역이 제대로 확보된다.

Monitoring

GClog

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xverbosegc:file=stdout -XX:+PrintGCDetails -Xloggc:/home1/irteam/apps/bloc/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCTimestamps -XX:+PrintTenuringDistribution

Java6_24Java7_2부터는 gc log roate를 지원

  • Java 6 Update 34

  • Java 7 Update 2 (but there is no reference to it in these release notes) There are three new JVM flags that can be used to enable and configure it:

-XX:+UseGCLogFileRotation

must be used with -Xloggc:<filename>;

-XX:NumberOfGClogFiles=<number of files>

must be >=1, default is one;

-XX:GCLogFileSize=<number>M (or K)

default will be set to 512K.

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/home/benelog/logs/gc-was1.log -XX:+UseGCLogFileRotation -XX:NumberOfGClogFiles=5 -XX:GCLogFileSize=256M 참고옵션: -XX:+PrintHeapAtGC

Log rotation 테스트

java -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:./gc-was1.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=256M -jar winstone.jar --webroot=./

java -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:./gc-was1.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=256M -jar jenkins.war

java -verbose:gc -XX:PermSize=256m -XX:MaxPermSize=100m -Xms100m -Xmx100m -server -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:./gc-was1.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=256M -jar jenkins.war

종합 설정 사례

CATALINA_OPTS="-server -Xms1024m -Xmx1024m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/home/benelog/logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=2M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/benelog/logs/heap-was1.hprof"

CATALINA_OPTS="-server -Xms1024m -Xmx1024m -XX:+UseG1GC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/home/benelog/logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/benelog/logs/heap-was1.hprof"

-XX:PermSize=128m -XX:MaxPermSize=128m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:-CMSConcurrentMTEnabled -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:+UseCMSInitiatingOccupancyOnly

사례

GC economics for 2GiB heap and 10GiB heap are totally different, keep it in mind while reading.

Scalability of different GC algorithmsMy experience tells that HotSpot’s CMS is most robust GC for 10-30Gb heaps (30Gb is my practical limit for single JVM so far).

CMS is only algorithm providing stable performance on 32Gb heap.

In general CPU efficiency of garbage collector is reverse proportion with memory efficiency.

if we would use different collection algorithms for young and old objects we can achieve better efficiency compared to single algorithm approach. Using different algorithms requires splitting of heap into two spaces. Cost of memory reclamation in old space will be higher but it will be compensated with lower death rate.

Criteria of good demography is to keep Ryoung >> Rold >> Rmid_aged (there R is death rate in corresponding lifetime diapason).

Shape of demography can be improved by tuning young collections (size of young space, size of survival spaces, tenuring threshold).

Another treat of GC efficiency is bad caching strategy, producing large amount of mid-aged garbage.

If first one or two generations are significantly large than older generations – your young collections are two frequent, you have to increase Eden size to increase period of collection. I

Using advises above and HotSpot’s CMS, I was able to keep GC pause on 32Gb Oracle Coherence storage node below 150ms on 8 core server.

HotSpot’s G1 also has potential but it is prone to same problem as JRockit – sporadically pause time becomes unreasonably long (few seconds).

BEA JRockit:

When does it make sence to call System.gc :

A short Primer to Java Memory Pool Sizing and Garbage Collectors

monitoring class loading and garbage collection : http://java.sun.com/developer/JDCTechTips/2004/tt0122.html#2

-XX:-DisableExplicitGC Disable calls to System.gc(), JVM still performs garbage collection when necessary.

-XX:+UserPartNewGC

-XX:+UseTLAB

-XX:+UseConcMarkSweepGC

VM options

자주쓰는 option

  • -XX:PermSize=128m -XX:MaxPermSize=256m

  • -XX:+CMSClassUnloadingEnabled : 쓰지 않는 클래스 정보 unloading

  • -XX:+CMSPermGenSweepingEnabled :