jvm參數(shù)類型、bin目錄下工具、gc算法/常見垃圾收集器
jvm參數(shù)類型
1.標(biāo)準(zhǔn)參數(shù)
????1.-vserion
????2.-help
2.X參數(shù)(非標(biāo)準(zhǔn)化參數(shù))
????1.-Xinit:解釋執(zhí)行
????2.-Xcomp:第一次使用就編譯成本地代碼
????3.-Xmixed:混合模式,jvm自己來決定是否編譯成本地代碼
3.XX參數(shù)
????1.非標(biāo)準(zhǔn)化參數(shù)
????2.相對(duì)不穩(wěn)定
????3.主要用于jvm調(diào)優(yōu)和debug
????4.類型
????????1)boolean類型-XX[+-]<name>表示啟用或者禁用name屬性
????????2)非boolean類型key-value,-XX<name>=<value>表示name屬性的值是value
-Xms = -XX:InitialHeapSize:初始化堆大小
-Xmx = -XX:MaxHeapSize:最大堆大小
運(yùn)行時(shí)jvm參數(shù)查看
-XX:+PrintFlagsFinal
=表示默認(rèn)值
:=表示用戶或者JVM修改后的值
例:java -XX:+PrintFlagsFinal -version
jps
jps -l
jinfo:
查看屬性值:
????jinfo -flags pid
查看最大堆:
????jinfo -flag MaxHeapSize pid
查看最大棧:
????jinfo -flag ThreadStackSize pid
查看元空間:
????jinfo -flag MetaspaceSize pid
jinfo -flags pid
Non-default VM flags:系統(tǒng)默認(rèn)的
Command line:自己配置的
jstat查看虛擬機(jī)統(tǒng)計(jì)信息
類加載
jstat -class pid 1000(毫秒) 10(次數(shù))
Loaded? Bytes? Unloaded? Bytes ? ? Time? ?
?17330 32996.8? ? ? ? 0 ? ? 0.0? ? ? 11.21
?17330 32996.8? ? ? ? 0 ? ? 0.0? ? ? 11.21
?17330 32996.8? ? ? ? 0 ? ? 0.0? ? ? 11.21
?17330 32996.8? ? ? ? 0 ? ? 0.0? ? ? 11.21
?17330 32996.8? ? ? ? 0 ? ? 0.0? ? ? 11.21
?17330 32996.8? ? ? ? 0 ? ? 0.0? ? ? 11.21
?17330 32996.8? ? ? ? 0 ? ? 0.0? ? ? 11.21
?17330 32996.8? ? ? ? 0 ? ? 0.0? ? ? 11.21
?17330 32996.8? ? ? ? 0 ? ? 0.0? ? ? 11.21
?17330 32996.8? ? ? ? 0 ? ? 0.0? ? ? 11.21
垃圾收集:-gc、-gcutil、-gccause、-gcnew、-gcold
jstat -gc pid
jstat -gc pid 1000(毫秒) 10(次數(shù))
?S0C? ? S1C? ? S0U? ? S1U? ? ? EC ? ? ? EU? ? ? ? OC ? ? ? ? OU ? ? ? MC ? ? MU? ? CCSC ? CCSU ? YGC ? ? YGCT? ? FGC? ? FGCT ? ? GCT? ?
209664.0 209664.0? 0.0 ? 111833.9 1677824.0 525792.0 6291456.0 ? 22526.1 ? 105860.0 102988.4 12288.0 11705.9 ? ? 17? ? 1.121 ? 4? ? ? 0.390? ? 1.511
S0C、S1C、S0U、S1U:s0和s1的總量與使用量
EC、EU:Eden區(qū)總量與使用量
OC、OU:old區(qū)總量與使用量
MC、MU:metaspache區(qū)總量與使用量
CCSC、CCSU:壓縮空間總量與使用量
YGC、YGCT:youngGC的次數(shù)與時(shí)間
FGC、FGCT:FullGC的次數(shù)與時(shí)間
GCT:總的GC時(shí)間
JIT編譯:
jstat -compiler pid
Compiled Failed Invalid ? Time ? FailedType FailedMethod
?? 18681? ? ? 5 ? ? ? 0 ? 118.76? ? ? ? ? 1 com/alibaba/fastjson/parser/DefaultJSONParser parseObject
jstat -printcompilation pid
Compiled? Size? Type Method
?? 18790? ? 862? ? 1 org/springframework/core/annotation/AnnotatedElementUtils hasAnnotation
jmap+MAT實(shí)戰(zhàn)內(nèi)存溢出
如果導(dǎo)出內(nèi)存映像文件
1.內(nèi)存溢出自動(dòng)導(dǎo)出
????-XX:+HeapDumpOnOutOfMemoryERROR
????-XX:HeapDumpPath=./
2.使用jmap命令手動(dòng)導(dǎo)出
????jps看下進(jìn)程號(hào)
????jmap -dump:format=b,file=xxx.hprof pid
????mat工具分析導(dǎo)出堆內(nèi)存導(dǎo)出文件
jstack實(shí)戰(zhàn)死循環(huán)與死鎖
????jstack pid
實(shí)戰(zhàn)死循環(huán)導(dǎo)致cpu飆高
????jstack pid > 文件
????top -p pid -H
????printf "%x" 線程號(hào)(轉(zhuǎn)化進(jìn)制)
基于JVisualVm的可視化監(jiān)控
????1.監(jiān)控本地tomcat
????2.監(jiān)控遠(yuǎn)程tomcat
????????修改jmx Catalina.sh
????3.監(jiān)控普通是java進(jìn)程
基于btrace的監(jiān)控調(diào)試
tomcat:
tomcat遠(yuǎn)程debug
????jdwp(java debug wire protocol)
????tomcat-manager監(jiān)控,需要配置user、manager
????psi-probe監(jiān)控,需要配置user、manager
tomcat調(diào)優(yōu)
1.內(nèi)存優(yōu)化
2.線程優(yōu)化:http.html
???? maxConnection
???? acceptCount
???? maxThreads
???? minSpareThreads
3.配置優(yōu)化
???? autoDeploy
???? enableLookups
???? reloadable
???? protocol
4.session優(yōu)化
????如果是jsp,可以禁用session
1.nginx
????1.ngx_http_stub_status監(jiān)控連接信息
????2.ngxtop監(jiān)控請求信息
????3.nginx-rrd圖形化監(jiān)控
????4.nginx優(yōu)化
?2.增加工作線程數(shù)和并發(fā)連接數(shù)
???? worker_processes
???? worker_connections
???? multi_accept on;
???? use epoll
?3.啟用長連接
?4.啟用緩存、壓縮
?5.操作系統(tǒng)優(yōu)化
?6.配置/etc/sysctl.conf
jvm層gc調(diào)優(yōu)
jvm的內(nèi)存結(jié)構(gòu)
1.運(yùn)行時(shí)數(shù)據(jù)區(qū)
? 程序計(jì)數(shù)器pc register
? 虛擬機(jī)棧jvm stacks
? 堆heap
? 方法區(qū)method area(非堆)
? 方法區(qū)里面有常量池
? 本地方法棧native method stacks
垃圾回收算法
????思想:枚舉根節(jié)點(diǎn),做可達(dá)性分析
????根節(jié)點(diǎn):類加載器、thread、虛擬機(jī)棧的本地變量表、static成員、常量引用、本地方法棧的變量等等
算法:
1.標(biāo)記清除
???? 算法分為標(biāo)記和清除兩個(gè)階段;首先標(biāo)記出所有需要回收的對(duì)線。在標(biāo)記完成后統(tǒng)一回收所有
???? 缺點(diǎn):效率不高、標(biāo)記和清除兩個(gè)過程的效率都不高,產(chǎn)生碎片。碎片太多會(huì)導(dǎo)致提前gc
2.復(fù)制
???? 它將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當(dāng)這一塊的內(nèi)存用完了,就將還存活的對(duì)象
???? 復(fù)制到另外一塊上面,然后再把使用過的內(nèi)存空間一次清理掉
???? 優(yōu)缺點(diǎn):實(shí)現(xiàn)簡單,運(yùn)行高效,但是空間利用率低
3.標(biāo)記整理
???? 標(biāo)記過程和標(biāo)記清除算法一樣,但是后續(xù)步驟不是直接對(duì)可回收對(duì)象進(jìn)行清理,而是讓所有存活的對(duì)象都向一端移動(dòng),然后清理掉邊界以外的內(nèi)存
???? 優(yōu)缺點(diǎn):沒有了內(nèi)存碎片,但是整理內(nèi)存比較耗時(shí)
分帶垃圾回收
????1.young區(qū)采用復(fù)制算法
????2.old區(qū)采用標(biāo)記清除或者標(biāo)記整理
對(duì)象分配
????1.對(duì)象優(yōu)先在eden區(qū)分配
????2.大對(duì)象直接進(jìn)入老年代:-XX:PretenureSizeThreshold
????3.長期存活的對(duì)象進(jìn)入老年代:-XX MaxTenuringThreshold
垃圾收集器:
????1.串行收集器serial:serial、serial old(一般不采用,client模式下的默認(rèn)收集器)
???? -XX:+UseSerialGC -XX:UseSerialOldGC(jd8以后廢棄)
????2.并行收集器:parallel:parallel scacenge、parallel old,吞吐量(server模式下的默認(rèn)收集器,根據(jù)cpu、內(nèi)存自動(dòng)判斷)
???? -XX:+UseParallelGC -XX:UseParallelOldGC
????3.并發(fā)收集器concurrent: cms、G1,停頓時(shí)間
1.響應(yīng)時(shí)間優(yōu)先
CMS(老年代收集器?):XX:+useConcMarkSweepGC -XX:+UseParNewGC
cms垃圾收集過程
???? 1.CMS inital mark:初始標(biāo)記Root,STW
???? 2.CMS concurrent mark:并發(fā)標(biāo)記
???? 3.CMS-concurrent-preclean:并發(fā)預(yù)清理
???? 4.CMS remark:重新標(biāo)記,STW
???? 5.CMS concurrent sweep:并發(fā)清除
???? 6.CMS-concurrent-reset:并發(fā)重置
缺點(diǎn):cpu敏感,浮動(dòng)垃圾,空間碎片
相關(guān)參數(shù):
???? 1.-XX:ConcGCThreads:并發(fā)的gc線程數(shù)
???? 2.-XX:+UseCMSCompactAtFullCollection:FullGC之后做壓縮
???? 3.-XX:CMSFullGCsbeforeCompaction:多少次fullGC之后壓縮一次
???? 4.-XX:CMSInitationOCcupancyFraction:觸發(fā)FullGC
???? 5.-XX:+UseCMSInitiationOccupancyOnly:是否動(dòng)態(tài)調(diào)
???? 6.-XX:+CMSScaveBeforeRemark:fullGC之前先做yongGC
???? 7.-XX:+CMSClassUnloadingEnabled:啟用回收Perm區(qū)
???? I-CMS:適用于單核或者雙核(jdk8后廢棄)
4.G1(java 8):-XX:+UseG1GC(jdk8推薦)
新生代和老年代收集器
???? 1.region
???? 2.SATB:Snapshot-At-The-Beginning:它是通過Root Tracing得到的,GC開始時(shí)候存活對(duì)象的快照
?????3.RSet:記錄了其他Region中的對(duì)象引用本Region中對(duì)象的關(guān)系,屬于points-into結(jié)構(gòu)(誰引用了我的對(duì)象)
YoungGC
???? 1.新對(duì)象進(jìn)入Eden區(qū)
???? 2.存活對(duì)象拷貝到Survivor區(qū)
???? 3.存活時(shí)間達(dá)到年齡閥值時(shí),對(duì)象晉升到old區(qū)
MixdGC
???? 1.不是FullGC,回收所有的young和部分的Old
???? 2.global concurrent marking:全局的并發(fā)標(biāo)記
MixdGC時(shí)機(jī)
是否需要切換到G1
5.ZGC(java 11)
G1調(diào)優(yōu)
即僅使用-Xms,-Xmx和暫停時(shí)間目標(biāo)-XX:MaxGCPauseMillis
并行vs并發(fā)
停頓時(shí)間vs吞吐量
垃圾收集器搭配
如何選擇垃圾收集器
可視化gc日志分析工具
1.在線工具:http://gceasy.io
allocated:分配的
promoted:晉升的
1)Key Performance Indicators:關(guān)鍵性能指標(biāo)
1.Throughput:吞吐量
2.Latency:響應(yīng)時(shí)間
Avg Pause GC Time :平均gc時(shí)間
Max Pause GC Time :最大gc時(shí)間
2.GCViewer
tomcat的gc調(diào)優(yōu)實(shí)戰(zhàn)
jvm字節(jié)碼指令
javap -verbose xxx.class > file
基于棧架構(gòu)
i++與++i字節(jié)碼指令是一樣的,效率一樣
字符串拼接:
每一次循環(huán)都會(huì)new一個(gè)StringBuilder
StringBuffer new一次
try-finally? return
String Constant Variable
intern
常見代碼優(yōu)化方法
1.盡量重用對(duì)象,不要循環(huán)創(chuàng)建對(duì)象,比如:for循環(huán)字符串拼接
2.容器類初始化的時(shí)候指定長度
3.ArrayList隨機(jī)遍歷快,linkedList添加刪除快
4.集合遍歷盡量減少重復(fù)計(jì)算
5.使用entry遍歷map
5.大數(shù)組復(fù)制用System.arraycopy
6.盡量使用基本類型而不是包裝類型
7.不要手動(dòng)調(diào)用system.gc()
8.及時(shí)消除過期對(duì)象的引用,防止內(nèi)存泄漏
9.盡量使用局部變量,減小變量的作用域
10.盡量使用非同步的容器ArrayList VS Vector
11.盡量減小同步作用范圍,synchronzied方法VS代碼塊
12.ThreadLocal緩存不安全的對(duì)象,SimpleDateFormat
13.盡量使用延遲加載
14.盡量減少使用反射,加緩存
15.盡量使用連接池、線程池、對(duì)象池、緩存
16.及時(shí)釋放資源,i/o流、socket、數(shù)據(jù)庫連接
17.慎用異常,不要用拋異常來表示正常的業(yè)務(wù)邏輯
18.String操作盡量少用正則表達(dá)式
19.日志輸出注意使用不同的級(jí)別
20.日志中參數(shù)拼接使用占位符