Java JVM調(diào)優(yōu)五大技能詳解
1.什么時(shí)候需要JVM調(diào)優(yōu)
- 應(yīng)用的響應(yīng)慢、CPU占用高
- 應(yīng)用吞吐量小,占用內(nèi)存空間過大
這些表象一般伴隨著頻繁的垃圾回收,或者OOM。
2.JVM調(diào)優(yōu)一般調(diào)什么
- 應(yīng)用占用的內(nèi)存(堆內(nèi)存,元空間內(nèi)存)
- 新生代老年代的大小,比例。
- 垃圾回收器的選擇。
堆內(nèi)存參數(shù)
| -Xms512m |
初始堆大小
默認(rèn)值:若未設(shè)置,初始值將是老年代和年輕代分配制內(nèi)存之和 |
---|
-Xmx1024m |
年輕代內(nèi)存相關(guān)參數(shù)
| -Xmn512m |
新生代的初始值及最大值。
默認(rèn)值:堆內(nèi)存的1/4(已經(jīng)分配的堆內(nèi)存的1/4)。 |
---|
-XX:NewSize=512m |
-XX:MaxNewSize=512m |
-XX:NewRatio=8 |
比如:-XX:NewRatio=8
表示:老年代內(nèi)存:年輕代內(nèi)存=8:1 |
| -XX:SurvivorRatio=8 |
新生代和存活區(qū)的比例
-XX:SurvivorRatio=8
表示存活區(qū):新生代=1:8 =》新生代占年輕代的8/10,每個(gè)存活區(qū)各占年輕代的1/10 |
元空間參數(shù)
| -XX:MetaspaceSize |
初始元空間大小
達(dá)到該值就會(huì)觸發(fā)垃圾收集進(jìn)行類型卸載 |
---|
-XX:MaxMetaspaceSize=256m |
3.JVM調(diào)優(yōu)基本步驟
首先在啟動(dòng)程序的時(shí)候
3.1添加GC日志相關(guān)的參數(shù)
-XX:+PrintGC:輸出GC日志 -XX:+PrintGCDetails:輸出GC的詳細(xì)日志 -XX:+PrintGCTimeStamps:輸出GC的時(shí)間戳(以基準(zhǔn)時(shí)間的形式) -XX:+PrintGCDateStamps:輸出GC的時(shí)間戳(以日期的形式,如2018-08-29T19:22:48.741-0800) -XX:+PrintHeapAtGC:在進(jìn)行GC的前后打印出堆的信息 -Xloggc:gc.log:日志文件的輸出路徑
3.2添加內(nèi)存溢出與Full gc前快照輸出參數(shù)
-XX:+HeapDumpOnOutOfMemoryError 發(fā)生內(nèi)存溢出時(shí)生成heapdump文件 -XX:+HeapDumpBeforeFullGC 發(fā)生Full gc前生成heapdump文件 -XX:HeapDumpPath:指定heapdump輸出路徑
3.3通過日志確定問題
3.3.1堆內(nèi)存不足
- 排查是否是設(shè)置的堆內(nèi)存過小,還是內(nèi)存溢出情況。
- 拿到當(dāng)時(shí)的內(nèi)存快照,用工具分析 jump用Mat工具分析。
3.3.2頻繁Full gc
- 考慮是否是新上線的代碼問題,有大對(duì)象占用,導(dǎo)致了頻繁YGC,進(jìn)而導(dǎo)致了晉升至年老代的對(duì)象增多,老年代達(dá)到內(nèi)存閾值觸發(fā) Full gc ;
- 考慮是否是新生代設(shè)置太小 ;
總結(jié):
若是代碼問題可通過版本控制工具找到本期變更的代碼,優(yōu)化代碼
若非代碼問題,可適當(dāng)增加堆內(nèi)存大小、新生代老年代的大小與比例 , 適當(dāng)增大新生代內(nèi)存大小。
4.監(jiān)控工具
4.1使用jstat 統(tǒng)計(jì)gc相關(guān)信息
jstat 是 jdk bin 下自帶工具,最多的是用來統(tǒng)計(jì)gc相關(guān)信息,使用步驟如下。
獲取進(jìn)程號(hào) ps -ef|grep 對(duì)應(yīng)進(jìn)程
例如我想統(tǒng)計(jì)jvm-demo.jar(進(jìn)程號(hào)27164)的gc信息,并且每隔3秒統(tǒng)計(jì)一次,可以執(zhí)行以下命令
jstat -gcutil 27164 3000
主要關(guān)注以下幾個(gè)。
s0、s1
:表示兩個(gè)survior區(qū)域的使用百分比e
:eden區(qū)域使用百分比o
:老年代使用百分比m
:metaspace(元數(shù)據(jù)空間)使用百分比ygc
:新生代gc次數(shù)ygct
:新生代gc累計(jì)總時(shí)間fgc
:full gc次數(shù)fgct
:full gc累計(jì)總時(shí)間gct
:gc累計(jì)總時(shí)間
若要進(jìn)一步查看上一次GC信息
jstat -gccause 27146 3000
LGCC
:上一次gc的原因,Allocation Failure是新生代滿了,進(jìn)行g(shù)cgcc
:當(dāng)前gc的原因,如果當(dāng)前沒有g(shù)c就no gc
4.2使用jmap命令查某時(shí)刻的JVM堆信息
使用步驟
- 獲取進(jìn)行 pid ps -ef|grep 對(duì)應(yīng)進(jìn)程
- 例如我想統(tǒng)計(jì)jvm-demo.jar(進(jìn)程號(hào)27164)的信息,并且每隔3秒統(tǒng)計(jì)一次,可以執(zhí)行以下命令
jmap -heap 2865
輸出內(nèi)容示例:
Attaching to process ID 27146, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.144-b01 using thread-local object allocation. Mark Sweep Compact GC #堆相關(guān)的配置信息 Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 104857600 (100.0MB) NewSize = 10485760 (10.0MB) MaxNewSize = 34930688 (33.3125MB) OldSize = 20971520 (20.0MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) #堆占用相關(guān)的配置信息 Heap Usage: New Generation (Eden + 1 Survivor Space): capacity = 12517376 (11.9375MB) used = 10708296 (10.212226867675781MB) free = 1809080 (1.7252731323242188MB) 85.54745020042539% used Eden Space: capacity = 11141120 (10.625MB) used = 10708272 (10.212203979492188MB) free = 432848 (0.4127960205078125MB) 96.11486098345588% used From Space: capacity = 1376256 (1.3125MB) used = 24 (2.288818359375E-5MB) free = 1376232 (1.3124771118164062MB) 0.0017438616071428572% used To Space: capacity = 1376256 (1.3125MB) used = 0 (0.0MB) free = 1376256 (1.3125MB) 0.0% used tenured generation: capacity = 27684864 (26.40234375MB) used = 27096504 (25.84123992919922MB) free = 588360 (0.5611038208007812MB) 97.87479541167332% used 15431 interned Strings occupying 2044328 bytes.
5.常用的調(diào)優(yōu)工具有哪些?
JDK內(nèi)置的命令行:jps
(查看jvm進(jìn)程信息)、jstat
(監(jiān)視jvm運(yùn)行狀態(tài)的,比如gc情況、jvm內(nèi)存情況、類加載情況等)、jinfo
(查看jvm參數(shù)的,也可動(dòng)態(tài)調(diào)整)、jmap
(生成dump文件的,在dump的時(shí)候會(huì)影響線上服務(wù))、jhat
(分析dump的,但是一般都將dump導(dǎo)出放到mat上分析)、jstack
(查看線程的)。
JDK內(nèi)置的可視化界面:JConsole
、VisualVM
,這兩個(gè)在QA環(huán)境壓測(cè)的時(shí)候很有用。
阿里巴巴開源的arthas:神器,線上調(diào)優(yōu)很方便,安裝和顯示效果都很友好
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
使用SpringBoot跨系統(tǒng)調(diào)用接口的方案
這篇文章主要介紹了使用SpringBoot跨系統(tǒng)調(diào)用接口的方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01Java SpringBoot詳解集成以及配置Swagger流程
Swagger 是一個(gè)規(guī)范和完整的框架,用于生成、描述、調(diào)用和可視化 RESTful 風(fēng)格的 Web 服務(wù)??傮w目標(biāo)是使客戶端和文件系統(tǒng)作為服務(wù)器以同樣的速度來更新。文件的方法,參數(shù)和模型緊密集成到服務(wù)器端的代碼,允許API來始終保持同步2021-10-10java數(shù)據(jù)庫(kù)開發(fā)之JDBC的完整封裝兼容多種數(shù)據(jù)庫(kù)
這篇文章主要介紹了java數(shù)據(jù)庫(kù)開發(fā)之JDBC的完整封裝兼容多種數(shù)據(jù)庫(kù),需要的朋友可以參考下2020-02-02Spring的BeanFactoryPostProcessor接口示例代碼詳解
這篇文章主要介紹了Spring的BeanFactoryPostProcessor接口,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02關(guān)于SpringMVC在Controller層方法的參數(shù)解析詳解
在SpringMVC中,控制器Controller負(fù)責(zé)處理由DispatcherServlet分發(fā)的請(qǐng)求,下面這篇文章主要給大家介紹了關(guān)于SpringMVC在Controller層方法的參數(shù)解析的相關(guān)資料,需要的朋友可以參考下2021-12-12使用java.util.Timer實(shí)現(xiàn)任務(wù)調(diào)度
這篇文章主要為大家詳細(xì)介紹了使用java.util.Timer實(shí)現(xiàn)任務(wù)調(diào)度,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03Java中LambdaQueryWrapper的常用方法詳解
這篇文章主要給大家介紹了關(guān)于Java中LambdaQueryWrapper常用方法的相關(guān)資料,lambdaquerywrapper是一個(gè)Java庫(kù),用于構(gòu)建類型安全的Lambda表達(dá)式查詢,需要的朋友可以參考下2023-11-11使用C3P0改造JDBC對(duì)數(shù)據(jù)庫(kù)的連接
這篇文章主要為大家詳細(xì)介紹了使用C3P0改造JDBC對(duì)數(shù)據(jù)庫(kù)的連接,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08