寫在前面
- 公司專案里看到,之前的專案都是在物理機部署的,而且大都是Server,沒搞過,這里整齊學習,
- 博文分為兩部分: 專案啟動腳本總結,java常用啟動引數,,啟動引數部分參考
流年似水,有些事情一下子過去了,有的事情很久也過不去,
流年似水,過去的事過去了,未過去的事也不能叫我驚訝,
但是歲月如流,一切都已發生過,發生過的事再也沒有改變的余地,
雖然歲月如流,什么都會過去,但總有些東西發生了就不能抹煞,
似水流年是一個人所有的一切,只有這個東西,才真正歸你所有,其余的一切,都是片刻的歡娛和不幸,轉眼間就已跑到那似水流年里去了, --------王小波
小專案啟動腳本
定時任務型別的小專案
#!/bin/sh
echo $path
mainclasspath="com.liruilong.uag.job.StartJob"
classpath="/demo/com_AAA/target/classes"
pathtmp=''
for jarpath in `ls /demo/com_AAA/lib/*.jar`
do
classpath=$classpath:$jarpath
done
classpath=$classpath:/demo/com_AAA/demo.jar
echo $classpath
echo $mainclasspath
nohup java -Xmx1024m -classpath $classpath $mainclasspath > /dev/null &
專案分開寫 start.sh
# 獲取腳本名字
PRG=$0
##
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '.*/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname $PRG`/$link"
fi
done
PRGDIR=`dirname ${PRG}`
MY_HOME=`cd .; pwd`
OLDCLASSPATH=${CLASSPATH}
CLASSPATH=.
for i in ./lib/*.jar ; do
CLASSPATH=${CLASSPATH}:$i
done
for i in ./jettyLib/*.jar ; do
CLASSPATH=${CLASSPATH}:$i
done
echo ${CLASSPATH}
if [ -z "$JAVA_HOME" ] ; then
JAVA=`which java`
if [ -z "$JAVA" ] ; then
echo "Cannot find JAVA. Please set your PATH."
exit 1
fi
JAVA_BINDIR=`dirname $JAVA`
JAVA_HOME=$JAVA_BINDIR/..
fi
if [ "$JAVACMD" = "" ] ; then
JAVACMD=$JAVA_HOME/bin/java
RMICMD=$JAVA_HOME/bin/rmiregistry
fi
if [ -f ${JAVA_HOME}/lib/tools.jar ] ; then
CLASSPATH=${CLASSPATH}:${JAVA_HOME}/lib/tools.jar
fi
if [ "$OLDCLASSPATH" != "" ]; then
CLASSPATH=${CLASSPATH}:${OLDCLASSPATH}
fi
#start npi_app
MY_HOME=`pwd`/..
instanceCount=`ps -ef|tr -s ' '|sort -n|grep PGM_ID=AZONE_NPI |awk '{print $2}'|wc -l`
if [ $instanceCount -gt 1 ]
then
echo 'AZONE_NPI already running !'
else
echo 'AZONE_NPI is starting ...'
MEM_ARGS="-verbosegc -Xms2048m -Xmx2048m -Xloggc:./log/gc.log"
$JAVACMD -Dserver.ip=10.128.92.66 -DPGM_ID=AZONE_NPI -DAPP_NAME=AZONE_NPI ${MEM_ARGS} -Dfile.encoding=GBK -Dconfigfile="./config/isap.xml" -cp .:./webRoot/WEB-INF/classes:log4j.properties:${CLASSPATH} com...xx.xx.xx.DispatcherCommand 4G_GROUP_NET >/dev/null &
fi
專案分開寫 stop.sh
pids=`ps -ef|grep java|grep AZONE_NPI |awk '{printf $2" "}'`
echo "will kill process ids:$pids"
kill -9 $pids
echo 'kill successed'
springboot 專案啟動腳本 ,沒有使用-jar 方式,
run.sh
#!/bin/sh
# ======JAVA 環境變數校驗========
# 宣告變數
ACTIVE_PROFILE=db,mq,redis,prod
TASK_GROUP_ID=1
# 如果 ${JAVA_HOME}/bin/java 不存在,那么把 ${JAVA_HOME} 的值給 JAVA_HOME
[ ! -e "${JAVA_HOME}/bin/java" ] && JAVA_HOME=${JAVA_HOME}
# 如果 $JAVA_HOME/bin/java 還不存在,那么/usr/local/jdk1.8.0_144 給 JAVA_HOME
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/local/jdk1.8.0_144
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/local/java/jdk
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/local/jdk
# 如果 $JAVA_HOME 為空
if [ -z "$JAVA_HOME" ] ; then
JAVA=${JAVA_HOME}/bin/java
# 如果當前用戶有可執行下面命令的權限
elif [ -x "$(command -v java)" ] ; then
# 把java命令的解釋器地址給 JAVA變數
JAVA=`command -v java`
else
# 提示錯誤,并重定向到標準錯誤
echo 'Error: java is not installed.' >&2
# 指定退出狀態碼 1 一般性未知錯誤,
exit 1
fi
# set ACTIVE_PROFILE default val, if ACTIVE_PROFILE is empty
# active_profile 沒有值,警告賦值,
if [ ! $ACTIVE_PROFILE ]; then
echo 'Warn: spring active profile[ACTIVE_PROFILE] not set in env, use default profile: dev'
ACTIVE_PROFILE='dev'
fi
# switch to parent dir of shell script.
# cd到當前腳本目錄下的上一層目錄
cd $(dirname $0)/..
# 把當前目錄給BASE_DIR
export BASE_DIR=$(pwd)
export CLASSPATH=.:${BASE_DIR}/config:${CLASSPATH}
################# app options ###############
APP_ID="demo"
MAIN_CLASS="com.liruilong.demo.DemoApplication"
################# user options ###############
USER_OPT="-Dlogging.config=${DATA_FILE_DIR:-.}/logback.xml -Dspring.profiles.active=${ACTIVE_PROFILE} -Dspring.config.location=classpath:../config/ -Drocketmq.client.log.loadconfig=false -Dfile.encoding=UTF-8"
################# java options ###############
JAVA_OPT="-server -Xmx1024m -Xms512m -Xmn512m"
# set JAVA_OPT_PARM default val, if JAVA_OPT_PARM is empty
if [ $JAVA_OPT_PARM ]; then
echo 'Warn: use the new [JAVA_OPT_PARM] by set in env'
JAVA_OPT="-server ${JAVA_OPT_PARM}"
fi
# jetty suggestion
JAVA_OPT="${JAVA_OPT} -verbose:gc"
JAVA_OPT="${JAVA_OPT} -Xloggc:./logs/gc.log -XX:-UseGCOverheadLimit -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
# r&d suggestion
JAVA_OPT="${JAVA_OPT} -XX:HeapDumpPath=./logs/dumpfile.hprof"
JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError"
# other like rocketmq
#JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch"
JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=1g"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking"
JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${BASE_DIR}/lib"
JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}"
################# java options ###############
################# pid ###############
#ONE JAR MORE INSTANCE
PID=$(ps -ef|grep "\\-DappId=${APP_ID}" | grep -v grep|awk '{print $2}')
#ONE JAR ONE INSTANCE
#PID=$(fuser ${JAR_FILE_NAME} 2>/dev/null | xargs echo)
################# pid ###############
start(){
if ! kill -0 ${PID} 2>/dev/null ;then
echo "${APP_ID} is starting!"
${JAVA} ${JAVA_OPT} ${USER_OPT} -DappId=${APP_ID} -DTASK_GROUP_ID=${TASK_GROUP_ID} ${MAIN_CLASS} >/dev/null 2>&1 &
else
echo "Failed to start '${APP_ID}',because it is running (pid:${PID})."
fi
}
stop(){
if kill -0 ${PID} 2>/dev/null ;then
kill ${PID}
echo "killing ${APP_ID}"
else
echo "Failed to stop '${APP_ID}',It is not running."
fi
}
status(){
if kill -0 ${PID} 2>/dev/null ;then
echo "${APP_ID} (pid:${PID}) is running."
else
echo "${APP_ID} is not running."
fi
}
case $1 in
start)
start;;
stop)
stop;;
status)
status;;
*)
echo "Usage: $0 start|stop|status"
esac
## 防止容器啟動后自動退出,導致應用無法啟動;
tail -f /dev/null
springboot 專案 容器類啟動腳本,使用 -jar方式
Dockerfile
#基礎鏡像docker build -t uncp-npi:v1.0.0 .
FROM centos7-java-pure:openjdk1.8.151
#維護人員
MAINTAINER liruilongs.github.io
#通過 ADD 指令復制代碼到目錄
ADD ./target/*.tar.gz /root/
#通過 RUN 指令創建日志目錄
RUN mkdir -p /root/logs/ \
&& touch /root/nohup.out \
&& chmod u+x /root/bin/run.sh
#通過 VOLUME 指令創建的掛載點
#VOLUME ["/root/logs"]
#暴露埠
EXPOSE 8430
#啟動腳本
ENTRYPOINT ["sh","/root/bin/run.sh"]
#切換作業目錄
WORKDIR /root
#啟動引數,會跟在 ENTRYPOINT 后面,
CMD ["start"]
run.sh
#!/bin/sh
# shell directory
# cd到當前腳本下
SH_DIR=$(cd "$(dirname "$0")"; pwd)
cd ${SH_DIR}
# 判斷java環境是否存在,
[ ! -e "${JAVA_HOME}/bin/java" ]
# 宣告全域變數
export JAVA_HOME
# 宣告java相關命令的解釋器
JAVA="${JAVA_HOME}/bin/java"
#JAVA="/CloudResetPwdUpdateAgent/depend/jre1.8.0_131/bin/java"
#JAVA="/usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java"
#JAVA="/usr/lib/jvm/openjdk-8u40-b25-linux-x64-10_feb_2015/java-se-8u40-ri/bin/java"
#JAVA="/usr/lib/jvm/java-se-8u40-ri/bin/java"
################# user options ###############
## 應用名稱,全域環境變數獲取
APP_ID="${APP_NAME}"
## 應用編碼:appCode引數為專案啟動執行緒類
APP_CODE="${APP_CODE}"
# 應用對應的jar包
JAR_FILE_NAME="Demo-2.0.0-SNAPSHOT.jar"
# 應用對應的日志檔案
COMMON_LOG_FILE="./logs/demo-inf.log"
#appCode引數為專案啟動執行緒類
#USER_OPT="-DappCode=INF_NATIVE,TEST -Dspring.config.location=classpath:./ -Dfile.encoding=UTF-8"
# 應用組態檔,檔案編碼
USER_OPT="-DappCode=${APP_CODE} -Dspring.config.location=classpath:./ -Dfile.encoding=UTF-8"
#DEBUG_ARGS="-Xdebug -agentlib:jdwp=transport=dt_socket,address=9999,server=y,suspend=n"
################# user options ###############
################# java options ###############
JAVA_OPT="-server -Xmx256m -Xms256m -Djasypt.encryptor.password=OSS3"
JAVA_OPT="${JAVA_OPT} -Xmn128m"
#JAVA_OPT="${JAVA_OPT} -Xbootclasspath/a:/home/iom_cloud_mysql/iom-cloud-inf-service/"
# jetty suggestion
JAVA_OPT="${JAVA_OPT} -verbose:gc"
#JAVA_OPT="${JAVA_OPT} -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCDetails"
JAVA_OPT="${JAVA_OPT} -Xloggc:./logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20m"
JAVA_OPT="${JAVA_OPT} -XX:+PrintTenuringDistribution"
JAVA_OPT="${JAVA_OPT} -XX:+PrintCommandLineFlags"
JAVA_OPT="${JAVA_OPT} -XX:+DisableExplicitGC"
JAVA_OPT="${JAVA_OPT} -XX:+UseConcMarkSweepGC"
JAVA_OPT="${JAVA_OPT} -XX:CMSInitiatingOccupancyFraction=80"
# r&d suggestion
JAVA_OPT="${JAVA_OPT} -XX:HeapDumpPath=./logs/dumpfile.hprof"
JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError"
# other like rocketmq
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
#JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch"
JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=15g"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking"
JAVA_OPT="${JAVA_OPT} ${EXTRAOPT}"
#JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=.:lib:${JAVA_HOME}/jre/lib/ext"
#JAVA_OPT="${JAVA_OPT} -Xbootclasspath/a:/home/iom_cloud_mysql/iom-cloud-inf-service/Demo-2.0.0-SNAPSHOT.jar"
#JAVA_OPT="${JAVA_OPT} -cp .:./lib:/home/iom_cloud_mysql/demo"
#echo ${JAVA_OPT}
# r&d
################# java options ###############
################# pid ###############
#ONE JAR MORE INSTANCE 一個 jar 多實體
PID=$(ps -ef|grep "\\-DappId=${APP_ID}" | grep -v grep|awk '{print $2}')
#ONE JAR ONE INSTANCE 一個jar 單實體
#PID=$(fuser ${JAR_FILE_NAME} 2>/dev/null | xargs echo)
################# pid ###############
## 啟動方法
## `kill -0 pid` 不發送任何信號,但是系統會進行錯誤檢查,所以經常用來檢查一個行程是否存在,存在回傳0 false ;不存在回傳1 true
start(){
## 判斷當前 行程是否存在
if ! kill -0 ${PID} 2>/dev/null ;then
## 輸出 行程開始啟動及對應的檔案
echo "${APP_ID} is starting! File is ${JAR_FILE_NAME}"
## 非控制臺下后臺啟動 將日志1&2輸出到指定位置
nohup ${JAVA} ${JAVA_OPT} ${USER_OPT} -DappId=${APP_ID} -jar ${JAR_FILE_NAME} >> ${COMMON_LOG_FILE} 2>&1 &
else
echo "Failed to start '${APP_ID}',because it is running (pid:${PID})."
fi
}
## 停止方法
stop(){
if kill -0 ${PID} 2>/dev/null ;then
# 正常結束行程,15是 kill 命令的默認信號,
kill ${PID}
echo "killing ${APP_ID}"
else
echo "Failed to stop '${APP_ID}',It is not running."
fi
}
status(){
if kill -0 ${PID} 2>/dev/null ;then
echo "${APP_ID} (pid:${PID}) is running."
else
echo "${APP_ID} is not running."
fi
}
case $1 in
start)
start;;
stop)
stop;;
status)
status;;
*)
echo "Usage: $0 start|stop|status"
esac
## 防止容器啟動后自動退出,導致應用無法啟動;
tail -f /dev/null
kill pid 和 kill -9 pid 的區別

| 信號編號 | 信號名 | 含義 |
|---|---|---|
| 0 | EXIT | 程式退出時收到該資訊, |
| 1 | HUP | 掛掉電話線或終端連接的掛起信號,這個信號也會造成某些行程在沒有終止的情況下重新初始化, |
| 2 | INT | 表示結束行程,但并不是強制性的,常用的 “Ctrl+C” 組合鍵發出就是一個 kill -2 的信號, |
| 3 | QUIT | 退出, |
| 9 | KILL | 殺死行程,即強制結束行程, |
| 11 | SEGV | 段錯誤, |
| 15 | TERM | 正常結束行程,是 kill 命令的默認信號, |
常用的kill 命令及其信號解釋
[kino@hadoop102 bin]$ jps
20097 Jps
19836 JobHistoryServer
19773 NodeManager
[kino@hadoop102 bin]$ kill 19836
# 殺死 PID 為 19836 的 JobHistoryServer 行程, 默認信號是 15, 正常停止
# 如果默認信號 15 不能殺死該行程, 則可以嘗試使用 信號9, 強制殺死行程
[kino@hadoop102 bin]$ jps
20115 Jps
19773 NodeManager
# PID 為 19836 的 JobHistoryServer 行程 已被殺死
使用“-1”信號,讓行程重啟,
[kino@hadoop102 bin]$ kill -1 19773
使用 “-9” 強制殺死行程
[kino@hadoop102 bin]$ kill -9 19773
我們在使用 kill 命令的時候, 可以傳入 信號編號,也可以傳入信號名
kill PID 等價于 kill -15 PID 等價于 kill -s TERM
kill -9 PID 等價與 kill -s SIGKILL PID
kill -1 PID 等價于 kill -s SIGHUP PID
java 啟動引數整理
java啟動引數共分為三類:
- 標準引數
(-),所有的JVM實作都必須實作這些引數的功能,而且向后兼容; - 非標準引數
(-X),默認jvm實作這些引數的功能,但是并不保證所有jvm實作都滿足,且不保證向后兼容; - 非
Stable引數(-XX),此類引數各個jvm實作會有所不同,將來可能會隨時取消,需要慎重使用;
一.標準引數

| 引數名稱 | 描述 |
|---|---|
-client | 設定jvm使用client模式,特點是啟動速度比較快,但運行時性能和記憶體管理效率不高,通常用于客戶端應用程式或者PC應用開發和除錯, |
-server | 設定jvm使server模式,特點是啟動速度比較慢,但運行時性能和記憶體管理效率很高,適用于生產環境,在具有64位能力的jdk環境下將默認啟用該模式,而忽略-client引數, |
-agentlib:libname[=options] | 用于裝載本地lib包; 其中 libname為本地代理庫檔案名,默認搜索路徑為環境變數PATH中的路徑,options為傳給本地庫啟動時的引數,多個引數之間用逗號分隔,在 Windows平臺上jvm搜索本地庫名為libname.dll的檔案,在linux上jvm搜索本地庫名為libname.so的檔案,搜索路徑環境變數在不同系統上有所不同,比如Solaries上就默認搜索LD_LIBRARY_PATH, 比如: |
-agentlib:hprof | 用來獲取jvm的運行情況,包括CPU、記憶體、執行緒等的運行資料,并可輸出到指定檔案中;windows中搜索路徑為JRE_HOME/bin/hprof.dll, |
-agentpath:pathname[=options] | 按全路徑裝載本地庫,不再搜索PATH中的路徑;其他功能和agentlib相同;更多的資訊待續,在后續的JVMTI部分會詳述, |
-classpath classpath -cp classpath |
告知 jvm搜索目錄名、jar檔案名、zip檔案名,之間用分號;分隔;使用
-classpath后
jvm將不再使用
CLASSPATH中的類搜索路徑,如果
-classpath和
CLASSPATH都沒有設定,則jvm使用
當前路徑(.)作為
類搜索路徑,
jvm搜索類的方式和順序為:
Bootstrap,
Extension,
User,
|
-Dproperty=value | 設定系統屬性名/值對,運行在此jvm之上的應用程式可用System.getProperty("property")得到value的值, 如果value中有空格,則需要用雙引號將該值括起來,如-Dname="space string", 該引數通常用于設定系統級全域變數值,如組態檔路徑,以便該屬性在程式中任何地方都可訪問, |
-enableassertions[:<package name>"..." | :<classname> ] -ea[:<package name>"..." | :<class name> ] | 上述引數就用來設定jvm是否啟動斷言機制(從JDK 1.4開始支持),預設時jvm關閉斷言機制, 用-ea可打開斷言機制,不加和classname時運行所有包和類中的斷言,如果希望只運行某些包或類中的斷言,可將包名或類名加到-ea之后,例如要啟動包com.wombat.fruitbat中的斷言,可用命令java -ea:com.wombat.fruitbat…, |
-disableassertions[:<package name>"..." | :<class ; ] -da[:<package name>"..." | :<class name> ] | 用來設定jvm關閉斷言處理,packagename和classname的使用方法和-ea相同,jvm默認就是關閉狀態,該引數一般用于相同package內某些class不需要斷言的場景,比如com.wombat.fruitbat需要斷言,但是com.wombat.fruitbat.Brickbat該類不需要,則可以如下運行: java -ea:com.wombat.fruitbat…-da:com.wombat.fruitbat.Brickbat , -enablesystemassertions -esa 激活系統類的斷言, -disablesystemassertions -dsa 關閉系統類的斷言, |
-jar | 指定以jar包的形式執行一個應用程式, 要這樣執行一個應用程式,必須讓jar包的manifest檔案中宣告初始加載的Main-class,當然那Main-class必須有public static void main(String[] args)方法, |
-javaagent:jarpath[=options] | 指定jvm啟動時裝入java語言設備代理, Jarpath 檔案中的mainfest檔案必須有Agent-Class屬性,代理類也必須實作公共的靜態public static void premain(String agentArgs, Instrumentation inst)方法(和main方法類似),當jvm初始化時,將按代理類的說明順序呼叫premain方法;具體參見 java.lang.instrument軟體包的描述, |
-verbose -verbose:class | 輸出jvm載入類的相關資訊,當jvm報告說找不到類或者類沖突時可此進行診斷, |
-verbose:gc | 輸出每次GC的相關情況, |
-verbose:jni | 輸出native方法呼叫的相關情況,一般用于診斷jni呼叫錯誤資訊, |
-version | 輸出java的版本資訊,比如jdk版本、vendor、model, |
-version:release | 指定class或者jar運行時需要的jdk版本資訊;若指定版本未找到,則以能找到的系統默認jdk版本執行;一般情況下,對于jar檔案,可以在manifest檔案中指定需要的版本資訊,而不是在命令列, release中可以指定單個版本,也可以指定一個串列,中間用空格隔開,且支持復雜組合,比如: -version:"1.5.0_04 1.5*&1.5.1_02+" 指定class或者jar需要jdk版本為1.5.0_04或者是1.5系列中比1.5.1_02更高的所有版本, |
-showversion | 輸出java版本資訊(與-version相同)之后,繼續輸出java的標準引數串列及其描述, |
-? -help | 輸出java標準引數串列及其描述, |
| – | – |
|---|---|
Bootstrap | 中的路徑是jvm自帶的jar或zip檔案,jvm首先搜索這些包檔案,用System.getProperty("sun.boot.class.path")可得到搜索路徑, |
Extension | 是位于JRE_HOME/lib/ext目錄下的jar檔案,jvm在搜索完Bootstrap后就搜索該目錄下的jar檔案,用System.getProperty("java.ext.dirs")可得到搜索路徑, |
User | 搜索順序為當前路徑.、CLASSPATH、-classpath,jvm最后搜索這些目錄,用`System.getProperty(“java.class.path”)可得到搜索路徑, |
二.非標準引數
-X 輸出非標準的引數串列及其描述,
以上的這些引數我們經常會在很多情況下用到多個的組合,比如我們在用JProfiler進行跟蹤監控時,需要在被監控java啟動引數中加上如下配置:-agentlib:jprofilerti=port=8849 -Xbootclasspath/a:/usr/local/jprofiler5/bin/agent.jar其中就用到兩個-agentlib和-X引數,bootclasspath引數的詳細資訊將會在非標準引數中詳細說明,

| 引數名稱 | 描述 |
|---|---|
-Xmixed | 混合模式執行 (默認) |
-Xint | 設定jvm以解釋模式運行,所有的位元組碼將被直接執行,而不會編譯成本地碼, |
-Xbatch | 關閉后臺代碼編譯,強制在前臺編譯,編譯完成之后才能進行代碼執行; 默認情況下,jvm在后臺進行編譯,若沒有編譯完成,則前臺運行代碼時以解釋模式運行, |
-Xbootclasspath:bootclasspath | 讓jvm從指定路徑(可以是分號分隔的目錄、jar、或者zip)中加載bootclass,用來替換jdk的rt.jar;若非必要,一般不會用到; |
| -Xbootclasspath/a:path | 將指定路徑的所有檔案追加到默認bootstrap路徑中; |
-Xbootclasspath/p:path | 讓jvm優先于bootstrap默認路徑加載指定路徑的所有檔案; |
-Xcheck:jni | 對JNI函式進行附加check;此時jvm將校驗傳遞給JNI函式引數的合法性,在本地代碼中遇到非法資料時,jmv將報一個致命錯誤而終止;使用該引數后將造成性能下降,請慎用, |
-Xfuture | 讓jvm對類檔案執行嚴格的格式檢查(默認jvm不進行嚴格格式檢查),以符合類檔案格式規范,推薦開發人員使用該引數, |
-Xnoclassgc | 關閉針對class的gc功能;因為其阻止記憶體回收,所以可能會導致OutOfMemoryError錯誤,慎用; |
-Xincgc | 開啟增量gc(默認為關閉);這有助于減少長時間GC時應用程式出現的停頓;但由于可能和應用程式并發執行,所以會降低CPU對應用的處理能力, |
-Xdiag | 顯示附加診斷訊息 |
-Xloggc:file | 與-verbose:gc功能類似,只是將每次GC事件的相關情況記錄到一個檔案中,檔案的位置最好在本地,以避免網路的潛在問題, 若與verbose命令同時出現在命令列中,則以-Xloggc為準, |
-Xmsn | 指定jvm堆的初始大小,默認為物理記憶體的1/64,最小為1M;可以指定單位,比如k、m,若不指定,則默認為位元組, |
-Xmxn | 指定jvm堆的最大值,默認為物理記憶體的1/4或者1G,最小為2M;單位與-Xms一致, |
-Xrs | 減少jvm對作業系統信號(signals)的使用,該引數從1.3.1開始有效; 從jdk1.3.0開始,jvm允許程式在關閉之前還可以執行一些代碼(比如關閉資料庫的連接池),即使jvm被突然終止; jvm 關閉工具通過監控控制臺的相關事件而滿足以上的功能;更確切的說,通知在關閉工具執行之前,先注冊控制臺的控制handler,然后對 CTRL_C_EVENT, CTRL_CLOSE_EVENT,CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT這幾類事件直接回傳true, 但如果jvm以服務的形式在后臺運行(比如servlet引擎),他能接收CTRL_LOGOFF_EVENT事件,但此時并不需要初始化關閉程式;為了避免類似沖突的再次出現,從jdk1.3.1開始提供-Xrs引數;當此引數被設定之后,jvm將不接收控制臺的控制handler,也就是說他不監控和處理CTRL_C_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, orCTRL_SHUTDOWN_EVENT事件, |
-Xssn | 設定單個執行緒堆疊的大小,一般默認為512k, |
| -Xdiag | 顯示附加診斷訊息 |
-Xbatch | 禁用后臺編譯 |
-Xprof | 輸出 cpu 組態檔資料,跟蹤正運行的程式,并將跟蹤資料在標準輸出輸出;適合于開發環境除錯 |
-Xshare:off | 不嘗試使用共享類資料 |
-Xshare:auto | 在可能的情況下使用共享類資料 (默認) |
-Xshare:on | 要求使用共享類資料, 否則將失敗, |
-XshowSettings | 顯示所有設定并繼續 |
-XshowSettings:all | 顯示所有設定并繼續 |
-XshowSettings:vm | 顯示所有與 vm 相關的設定并繼續 |
-XshowSettings:properties | 顯示所有屬性設定并繼續 |
-XshowSettings:locale | 顯示所有與區域設定相關的設定并繼續 |
上面這些引數中,比如-Xmsn、-Xmxn……都是我們性能優化中很重要的引數; -Xprof、-Xloggc:file等都是在沒有專業跟蹤工具情況下排錯的好手;
三.非Stable(穩定)引數
用-XX作為前綴的引數串列在jvm中可能是不健壯的,SUN也不推薦使用,后續可能會在沒有通知的情況下就直接取消了;但是由于這些引數中的確有很多是對我們很有用的,比如我們經常會見到的-XX:PermSize、-XX:MaxPermSize等等; 下面我們將就Java HotSpot VM中-XX:的可配置引數串列進行描述; 這些引數可以被松散的聚合成三類`:
- 行為引數(Behavioral Options) :用于改變jvm的一些基礎行為;
- 性能調優(Performance Tuning) :用于jvm的性能調優;
- 除錯引數(Debugging Options) :一般用于打開跟蹤、列印、輸出等jvm引數,用于顯示jvm更加詳細的資訊;
由于sun官方檔案中對各引數的描述也都非常少(大多只有一句話),而且大多涉及OS層面的東西,很難描述清楚,所以以下是挑選了一些我們開發中可能會用得比較多的配置項,
行為引數:
| 引數及其默認值 | 描述 |
|---|---|
| -XX:-DisableExplicitGC | 禁止呼叫System.gc();但jvm的gc仍然有效 |
| -XX:+MaxFDLimit | 最大化檔案描述符的數量限 |
| -XX:+ScavengeBeforeFullG | 新生代GC優先于Full GC執 |
| -XX:+UseGCOverheadLimi | 在拋出OOM之前限制jvm耗費在GC上的時間比 |
| -XX:-UseConcMarkSweepG | 對老生代采用并發標記交換演算法進行GC |
| -XX:-UseParallelG | 啟用并行GC |
| -XX:-UseParallelOldG | 對Full GC啟用并行,當-XX:-UseParallelGC啟用時該項自動啟 |
| -XX:-UseSerialG | 啟用串行GC |
| -XX:+UseThreadPrioritie | 啟用本地執行緒優先 |
上面表格中黑體的三個引數代表著jvm中GC執行的三種方式,即串行、并行、并發;
串行(SerialGC)是jvm的默認GC方式,一般適用于小型應用和單處理器,演算法比較簡單,GC效率也較高,但可能會給應用帶來停頓;并行(ParallelGC)是指GC運行時,對應用程式運行沒有影響,GC和app兩者的執行緒在并發執行,這樣可以最大限度不影響app的運行;并發(ConcMarkSweepGC)是指多個執行緒并發執行GC,一般適用于多處理器系統中,可以提高GC的效率,但演算法復雜,系統消耗較大;
性能調優引數串列:
日常性能調優中基本上都會用到以下的這幾個屬性
| 引數及其默認值 | 描述 |
|---|---|
| -XX:LargePageSizeInBytes=4m | 設定用于Java堆的大頁面尺寸 |
| -XX:MaxHeapFreeRatio=70 | GC后java堆中空閑量占的最大比例 |
| -XX:MaxNewSize=size | 新生成物件能占用記憶體的最大值 |
| -XX:MaxPermSize=64m | 老生代物件能占用記憶體的最大值 |
| -XX:MinHeapFreeRatio=40 | GC后java堆中空閑量占的最小比例 |
| -XX:NewRatio=2 | 新生代記憶體容量與老生代記憶體容量的比例 |
| -XX:NewSize=2.125m | 新生代物件生成時占用記憶體的默認值 |
| -XX:ReservedCodeCacheSize=32m | 保留代碼占用的記憶體容量 |
| -XX:ThreadStackSize=512 | 設定執行緒堆疊大小,若為0則使用系統默認值 |
| -XX:+UseLargePages | 使用大頁面記憶體 |
除錯引數串列:
| 引數及其默認值 | 描述 |
|---|---|
| -XX:-CITime | 列印消耗在JIT編譯的時間 |
| -XX:ErrorFile=./hs_err_pid.log | 保存錯誤日志或者資料到檔案中 |
| -XX:-ExtendedDTraceProbes | 開啟solaris特有的dtrace探針 |
| -XX:HeapDumpPath=./java_pid.hprof | 指定匯出堆資訊時的路徑或檔案名 |
| -XX:-HeapDumpOnOutOfMemoryError | 當首次遭遇OOM時匯出此時堆中相關資訊 |
| -XX:OnError=";" | 出現致命ERROR之后運行自定義命令 |
| -XX:OnOutOfMemoryError=";" | 當首次遭遇OOM時執行自定義命令 |
| -XX:-PrintClassHistogram | 遇到Ctrl-Break后列印類實體的柱狀資訊,與jmap -histo功能相同 |
| -XX:-PrintConcurrentLocks | 遇到Ctrl-Break后列印并發鎖的相關資訊,與jstack -l功能相同 |
| -XX:-PrintCommandLineFlags | 列印在命令列中出現過的標記 |
| -XX:-PrintCompilation | 當一個方法被編譯時列印相關資訊 |
| -XX:-PrintGC | 每次GC時列印相關資訊 |
| -XX:-PrintGC Details | 每次GC時列印詳細資訊 |
| -XX:-PrintGCTimeStamps | 列印每次GC的時間戳 |
| -XX:-TraceClassLoading | 跟蹤類的加載資訊 |
| -XX:-TraceClassLoadingPreorder | 跟蹤被參考到的所有類的加載資訊 |
| -XX:-TraceClassResolution | 跟蹤常量池 |
| -XX:-TraceClassUnloading | 跟蹤類的卸載資訊 |
| -XX:-TraceLoaderConstraints | 跟蹤類加載器約束的相關資訊 |
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/295165.html
標籤:java
上一篇:jmap的使用以及記憶體溢位分析
