|
| 1 | +#!/bin/bash |
| 2 | +# |
| 3 | +# 启动脚本 |
| 4 | +# 该脚本部分取自 vjkit,都做了注释,按需引用 |
| 5 | +# 仅支持 java 11+ |
| 6 | +# |
| 7 | +# 支持的环境变量: |
| 8 | +# - $NAME 应用名称 |
| 9 | +# - $JAVA_OPTS jvm 参数 |
| 10 | +# - $JAVA_AGENT jvm agent |
| 11 | + |
| 12 | +# 基本参数 |
| 13 | +# appid 关系到日志文件名和一些其他的设置 |
| 14 | +APPID=${NAME:-application} |
| 15 | + |
| 16 | +BASEPATH=$(cd `dirname $0`; pwd) |
| 17 | +JAVA_VERSION=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}') |
| 18 | + |
| 19 | +# ************************************************************** |
| 20 | + |
| 21 | +# ************************** 以下JVM部分 ************************ |
| 22 | + |
| 23 | +# Enable coredump 容器环境暂不清楚是否可用,观望一手 |
| 24 | +# ulimit -c unlimited |
| 25 | + |
| 26 | +## Memory Options, 根据实际情况进行调整,建议为内存总量一半, 容器环境,靠容器本体限制 |
| 27 | +# MEM_OPTS="-Xmx512m -Xms512m -XX:NewRatio=1 -XX:MetaspaceSize=192M -XX:MaxMetaspaceSize=192M" |
| 28 | + |
| 29 | +# 启动时预申请内存 |
| 30 | +# MEM_OPTS="$MEM_OPTS -XX:+AlwaysPreTouch" |
| 31 | + |
| 32 | +# 如果线程数较多,函数的递归较少,线程栈内存可以调小节约内存,默认1M。 |
| 33 | +MEM_OPTS="$MEM_OPTS -Xss512k" |
| 34 | + |
| 35 | +# 堆外内存的最大值默认约等于堆大小,可以显式将其设小,获得一个比较清晰的内存总量预估 |
| 36 | +#MEM_OPTS="$MEM_OPTS -XX:MaxDirectMemorySize=2g" |
| 37 | + |
| 38 | +# 根据JMX/VJTop的观察,调整二进制代码区大小避免满了之后不能再JIT,JDK7/8,是否打开多层编译的默认值都不一样 |
| 39 | +#MEM_OPTS="$MEM_OPTS -XX:ReservedCodeCacheSize=240M" |
| 40 | + |
| 41 | + |
| 42 | +## GC Options## |
| 43 | + |
| 44 | +GC_OPTS="-XX:+UseG1GC" |
| 45 | + |
| 46 | +# System.gc() 使用并行算法 |
| 47 | +GC_OPTS="$GC_OPTS -XX:+ExplicitGCInvokesConcurrent" |
| 48 | + |
| 49 | +# 根据应用的对象生命周期设定,减少事实上的老生代对象在新生代停留时间,加快YGC速度 |
| 50 | +# GC_OPTS="$GC_OPTS -XX:MaxTenuringThreshold=3" |
| 51 | + |
| 52 | +# 如果OldGen较大,加大YGC时扫描OldGen关联的卡片,加快YGC速度,默认值256较低 |
| 53 | +# GC_OPTS="$GC_OPTS -XX:+UnlockDiagnosticVMOptions -XX:ParGCCardsPerStrideChunk=1024" |
| 54 | + |
| 55 | +# 如果JVM并不独占机器,机器上有其他较繁忙的进程在运行,将GC线程数设置得比默认值(CPU核数*5/8 )更低以减少竞争,反而会大大加快YGC速度。 |
| 56 | +#GC_OPTS="$GC_OPTS -XX:ParallelGCThreads=12 -XX:ConcGCThreads=6" |
| 57 | + |
| 58 | + |
| 59 | +## GC log Options, only for JDK7/JDK8 ## |
| 60 | + |
| 61 | +# 默认使用/dev/shm 内存文件系统避免在高IO场景下写GC日志时被阻塞导致STW时间延长 |
| 62 | +if [ -d /dev/shm/ ]; then |
| 63 | + GC_LOG_FILE=/dev/shm/gc-${APPID}.log |
| 64 | +else |
| 65 | + mkdir -p ${BASEPATH}/gc/ |
| 66 | + GC_LOG_FILE=${BASEPATH}/gc/gc-${APPID}.log |
| 67 | +fi |
| 68 | + |
| 69 | +if [ -f ${GC_LOG_FILE} ]; then |
| 70 | + GC_LOG_BACKUP=${BASEPATH}/gc/gc-${APPID}-$(date +'%Y%m%d_%H%M%S').log |
| 71 | + echo "saving gc log ${GC_LOG_FILE} to ${GC_LOG_BACKUP}" |
| 72 | + mkdir -p ${BASEPATH}/gc/ |
| 73 | + mv ${GC_LOG_FILE} ${GC_LOG_BACKUP} |
| 74 | +fi |
| 75 | + |
| 76 | +#打印GC日志,包括时间戳,晋升老生代失败原因,应用实际停顿时间(含GC及其他原因) 暂且没摸清java11该怎么打印 |
| 77 | +#GCLOG_OPTS="-Xloggc:${GC_LOG_FILE} -XX:+PrintGCDetails -Xlog::::time,level,tags,safepoint" |
| 78 | + |
| 79 | + |
| 80 | +# 打印安全点日志,找出GC日志里非GC的停顿的原因,会损失很多性能 |
| 81 | +#GCLOG_OPTS="$GCLOG_OPTS -XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1 -XX:+UnlockDiagnosticVMOptions -XX:-DisplayVMOutput -XX:+LogVMOutput -XX:LogFile=/dev/shm/vm-${APPID}.log" |
| 82 | + |
| 83 | + |
| 84 | +## Optimization Options## |
| 85 | + |
| 86 | +OPTIMIZE_OPTS="-XX:-UseBiasedLocking -XX:AutoBoxCacheMax=20000 -Djava.security.egd=file:/dev/./urandom" |
| 87 | + |
| 88 | + |
| 89 | +# 关闭PerfData写入,避免高IO场景GC时因为写PerfData文件被阻塞,但会使得jstats,jps不能使用 |
| 90 | +#OPTIMIZE_OPTS="$OPTIMIZE_OPTS -XX:+PerfDisableSharedMem" |
| 91 | + |
| 92 | +# 关闭多层编译,减少应用刚启动时的JIT导致的可能超时,以及避免部分函数C1编译后最终没被C2编译。 但导致函数没有被初始C1编译。 |
| 93 | +#if [[ "$JAVA_VERSION" > "1.8" ]]; then |
| 94 | +# OPTIMIZE_OPTS="$OPTIMIZE_OPTS -XX:-TieredCompilation" |
| 95 | +#fi |
| 96 | + |
| 97 | +# 如果希望无论函数的热度如何,最终JIT所有函数,关闭GC时将函数调用次数减半。 |
| 98 | +#OPTIMIZE_OPTS="$OPTIMIZE_OPTS -XX:-UseCounterDecay" |
| 99 | + |
| 100 | +## Trouble shooting Options## |
| 101 | +mkdir -p ${BASEPATH}/jvm/ |
| 102 | +SHOOTING_OPTS="-XX:+PrintCommandLineFlags -XX:-OmitStackTraceInFastThrow -XX:ErrorFile=${BASEPATH}/jvm/hs_err_%p.log" |
| 103 | + |
| 104 | + |
| 105 | +# OOM 时进行HeapDump,但此时会产生较高的连续IO,如果是容器环境,有可能会影响他的容器 |
| 106 | +# mkdir -p ${BASEPATH}/dump/ |
| 107 | +# SHOOTING_OPTS="$SHOOTING_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${BASEPATH}/dump/" |
| 108 | + |
| 109 | + |
| 110 | +# 在非生产环境,打开JFR进行性能记录(生产环境要收License) |
| 111 | +#SHOOTING_OPTS="$SHOOTING_OPTS -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints" |
| 112 | + |
| 113 | + |
| 114 | +## JMX Options## |
| 115 | + |
| 116 | +#开放JMX本地访问,设定端口号,可使用 jconsole 介入。容器场景不能限定 localhost -Djava.rmi.server.hostname=127.0.0.1 |
| 117 | +JMX_OPTS="-Dcom.sun.management.jmxremote.port=9012 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" |
| 118 | + |
| 119 | + |
| 120 | +## Other Options## |
| 121 | + |
| 122 | +## 远程 debug |
| 123 | +# OTHER_OPTS="-Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005" |
| 124 | + |
| 125 | + |
| 126 | +## All together ## |
| 127 | + |
| 128 | +JAVA_OPTS=${JAVA_OPTS:-"$MEM_OPTS $GC_OPTS $GCLOG_OPTS $OPTIMIZE_OPTS $SHOOTING_OPTS $JMX_OPTS $OTHER_OPTS"} |
| 129 | +echo JAVA_OPTS=$JAVA_OPTS |
| 130 | + |
| 131 | +# **************************************************************** |
| 132 | + |
| 133 | +exec java $JAVA_OPTS $JAVA_AGENT org.springframework.boot.loader.JarLauncher "$@" |
0 commit comments