Java

JVM GC 설정

gregorio 2018. 6. 7. 10:56

Tomcat을 사용하는 경우 ../bin/setenv.sh에 다음과 같이 추가한다.


Garbage Collection 방식은 Parallel GC를 적용하고 있으며, New 영역에 256m를 할당하였다.


■Parallel GC 설정

#!/bin/sh


export JAVA_HOME=/engn001/jdk1.7.0_80

# Configuration Tomcat log file

CATALINA_OUT="/logs001/apache-tomcat-7.0.76/catalina.out"

#Configuration JVM Heap Size

JAVA_OPTS=" ${JAVA_OPTS} -Xms1280m -Xmx1280m -XX:MaxPermSize=256m -XX:NewSize=256m –XX:MaxNewSize=256m -XX:SurvivorRatio=16"

#Start Configuration GC

JAVA_OPTS=" ${JAVA_OPTS} -verbose:gc -XX:+DisableExplicitGC -Xloggc:/logs001/apache-tomcat-7.0.76/gc_`date +"%Y%m%d"`.log"

JAVA_OPTS=" ${JAVA_OPTS} -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC"

#Apply Parallel GC

JAVA_OPTS=" ${JAVA_OPTS} -XX:+UseParallelGC  -XX:ParallelGCThreads=6 -XX:+UseParallelOldGC"

#End Configuration GC

JAVA_OPTS=" ${JAVA_OPTS} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs001/heap/portal.hprof"

#Start Configuration SCOUT

JAVA_OPTS=" ${JAVA_OPTS} -javaagent:${SCOUTER_AGENT_DIR}/scouter.agent.jar"

JAVA_OPTS=" ${JAVA_OPTS} -Dscouter.config=${SCOUTER_AGENT_DIR}/conf/scouter.conf"

JAVA_OPTS=" ${JAVA_OPTS} -Dobj_name=SEHATI-PORTAL"

#End Configuration SCOUT



■ CMS GC 설정

# Base settings and GC logging

-server -XX:+AlwaysPreTouch  # First should be default, but we make it explicit, second pre-zeroes memory mapped pages on JVM startup -- improves runtime performance

# -Xloggc:gc-%t.log  # CUSTOMIZE LOCATION HERE - $path/gc-%t.log -- the %t in the gc log file path is so we get a new file with each JVM restart

-XX:NumberOfGCLogFiles=5 -XX:+UseGCLogFileRotation -XX:GCLogFileSize=20m # Limits the number of files, logs to folder 

-XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCCause

-XX:+PrintTenuringDistribution -XX:+PrintReferenceGC -XX:+PrintAdaptiveSizePolicy # gather info on object age & reference GC time for further tuning if needed.


# G1 specific settings -- probably should be default for multi-core systems with >2 GB of heap (below that, default is probably fine)

-XX:+UseG1GC

-XX:+UseStringDeduplication

-XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20  # Prevents G1 undersizing young gen, which otherwise causes a cascade of issues

-XX:+ParallelRefProcEnabled # parallelize reference processing, reducing young and old GC times. We use a LOT of weak references, so should have big impact.

-XX:+ExplicitGCInvokesConcurrent  # Avoid explicit System.gc() call triggering full GC, instead trigger G1

-XX:+UnlockDiagnosticVMOptions -XX:G1SummarizeRSetStatsPeriod=1 # Additional logging for G1 status

-XX:MaxMetaspaceExpansion=64M  # Avoids triggering full GC when we just allocate a bit more metaspace, and metaspace automatically gets cleaned anyway


# Tuned CMS GC - probably not worth using though (prefer G1 or default parallel GC if heap is <2 GB or so)

-XX:+UseConcMarkSweepGC

-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses # fixes issues with superlong explicit GC cycles (switches to concurrent GC, but also enables class unloading so we don't get memory leaks).

-XX:+CMSParallelRemarkEnabled -XX:+ParallelRefProcEnabled # parallelize re-marking and reference processing. The first will reduce full GC time, the latter should reduce both GC times -- we use a LOT of weak references, so should have big impact.

-XX:+CMSClassUnloadingEnabled # allows GC of classloaders & classes (important because we do some dynamic loading and because of groovy).

-XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark # will force young gen GC before full GC (reduces full GC duration)

# Based on GC logs but may need refining, somewhere from 1:1 to 1:3 ratio is best because Jenkins makes mostly young garbage, cap at 3 G to limit minor GC pause duration

-XX:NewSize=512m -XX:MaxNewSize=3g -XX:NewRatio=2  


# Options NOT to use so far:

# * -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent> - Generally suggested, but we don't have good benchmarks to collect these. So far we haven't done it


# Settings we *may* want to add for CMS but need more data for

#-Xms4g # because realistically allocating anything under 4 GB just increases startup time. We need that much RAM. Optional.

#-XX:NewSize=512m -XX:MaxNewSize=3g -XX:NewRatio=2 # start young gen somewhere reasonable and let it grow, but not too big (3 GB is a compromise b/w young GC pause time and the full GC pause time, the latter of which we know to be quite good even with a 10+ GB old gen heap)


# LOW-MEMORY use Jenkins, I.E. Jenkins on OpenShift, I have been using this for a long time to run Jenkins on an AWS t2.micro

# Will run A-OK with -Xmx384m if you limit load & workers

-XX:+UseSerialGC -XX:MinHeapFreeRatio=15 -XX:MaxHeapFreeRatio=30  -XX:MinMetaspaceFreeRatio=10 -XX:MaxMetaspaceFreeRatio=20 

# -XX:MaxMetaspaceSize=128m  -XX:CompressedClassSpaceSize=128m # Tweak to your needs.  This will run a decent-sized Jenkins however.  Too low == crashes

# Make sure to limit metaspace too, i.e. -XX:MaxMetaspaceSize=128m because it allocates a lot of RAM for that 


The over parameters are referred at https://gist.github.com/svanoort/66a766ea68781140b108f465be45ff00