JVM性能調(diào)優(yōu)實(shí)現(xiàn)原理及配置
1、JVM內(nèi)存模型
總結(jié):可以發(fā)現(xiàn)最明顯的一個(gè)變化是元空間從虛擬機(jī)轉(zhuǎn)移到了本地內(nèi)存。默認(rèn)情況下,元數(shù)據(jù)空間大小僅受限于本地內(nèi)存, 這意味著以后不會(huì)因?yàn)橛谰么笮〔粔蚨鴴伋鯫OM異常了。 jdk1.8以前,HotSpot VM將class和類(lèi)的jar包數(shù)據(jù)存儲(chǔ)在PermGen里, PermGen大小是固定的,而且項(xiàng)目之間無(wú)法公用公有的class,所以很容易碰到OOM異常。改成MateSpace后, 各個(gè)項(xiàng)目會(huì)共享同樣的class空間。比如多個(gè)項(xiàng)目都引用了apache-common包, 在MateSpace中只會(huì)存儲(chǔ)一份的apache-common的class,提高了內(nèi)存的利用率,垃圾回收更有效。
2、JVM堆內(nèi)存常用參數(shù)
參數(shù) | 描述 |
---|---|
-Xms | 堆內(nèi)存初始大小,單位m、g |
-Xmx(MaxHeapSize) | 堆內(nèi)存最大允許大小,一般不要大于物理內(nèi)存的80% |
-XX:PermSize | 非堆內(nèi)存初始大小,一般應(yīng)用設(shè)置初始化200m,最大1024m就夠了 |
-XX:MaxPermSize | 非堆內(nèi)存最大允許大小 |
-XX:NewSize(-Xns) | 年輕代內(nèi)存初始大小 |
-XX:MaxNewSize(-Xmn) | 年輕代內(nèi)存最大允許大小,也可以縮寫(xiě) |
-XX:SurvivorRatio=8 | 年輕代中Eden區(qū)與Survivor區(qū)的容量比例值,默認(rèn)為8,即8:1 |
-Xss | 堆棧內(nèi)存大小 |
3、GC(Garbage Collection)算法
這里的GC具體指的是新生代的復(fù)制算法
首先貼一張網(wǎng)上盜來(lái)的大圖,用它來(lái)說(shuō)明一下GC的過(guò)程
內(nèi)存分配策略:
大多數(shù)情況下,對(duì)象在新生代的Eden中分配。當(dāng)Eden區(qū)沒(méi)有足夠的空間進(jìn)行分配時(shí),虛擬機(jī)將發(fā)起一次Minor GC,而大對(duì)象(需要大量連續(xù)內(nèi)存空間的Java對(duì)象,類(lèi)似長(zhǎng)字符串和數(shù)組)將通過(guò)分配擔(dān)保機(jī)制直接進(jìn)入老年代。
Minor GC——復(fù)制算法具體過(guò)程:
將Eden和S0中還存活著的對(duì)象一次性的復(fù)制到S1中,并且清理掉Eden與S0的空間。如果S1放不下還存活著的對(duì)象,那這些對(duì)象將通過(guò)分配擔(dān)保機(jī)制進(jìn)入老年代?!驹砩想S時(shí)保持S0和S1有一個(gè)是空的,用來(lái)存下一次的對(duì)象】
Eden區(qū)快滿(mǎn)的時(shí)候,會(huì)進(jìn)行上一步類(lèi)似操作,將Eden和S1區(qū)的年紀(jì)大的對(duì)象放到S0區(qū)【此時(shí)S1區(qū)就是空的】
直到Eden區(qū)快滿(mǎn),S0或者S1也快滿(mǎn)的時(shí)候,這時(shí)候就把這兩個(gè)區(qū)的年紀(jì)大的對(duì)象放到Old區(qū)。
依次循環(huán),直到Old區(qū)也快滿(mǎn)的時(shí)候,Eden區(qū)也快滿(mǎn)的時(shí)候,會(huì)對(duì)整個(gè)這一塊內(nèi)存區(qū)域進(jìn)行一次大清洗(FullGC),騰出內(nèi)存,為之后的對(duì)象創(chuàng)建,程序運(yùn)行騰地方。
新生代GC(Minor GC):指發(fā)生在新生代的垃圾回收動(dòng)作,因?yàn)閖ava對(duì)象大多具備朝生夕滅的特征,所以Minor GC發(fā)生的特別頻繁,
一般回收速度也很快。
老年代GC(Major GC/Full GC):指發(fā)生在老年代的GC,出現(xiàn)了Major GC,至少會(huì)伴隨一次的MinorGC(但非絕對(duì),
在Parallel Scavenge收集器的收集策略里就有直接進(jìn)行Minor GC的策略選擇過(guò)程)。Major GC的速度一般比Minor GC慢10倍以上。
4、JVM參數(shù)配置
在jdk1.8以前,生產(chǎn)環(huán)境一般有如下配置
-XX:PermSize=512M -XX:MaxPermSize=1024M
表示在JVM里存儲(chǔ)Java類(lèi)信息,常量池和靜態(tài)變量的永久代區(qū)域初始大小為512M,最大為1024M。在項(xiàng)目啟動(dòng)后,這個(gè)值是固定的,如果項(xiàng)目class過(guò)多,很可能遇到OutOfMemoryError: PermGen異常。
升級(jí)JDK1.8之后,上面的perm配置已經(jīng)變成
-XX:MetaspaceSize=512M XX:MaxMetaspaceSize=1024M
MetaspaceSize如果不做配置,通過(guò)jinfo查看默認(rèn)MetaspaceSize大小(約21M),MaxMetaspaceSize很大很大,前面說(shuō)過(guò)MetaSpace只受本地內(nèi)存大小限制。
jinfo -flag MetaspaceSize 1234 #結(jié)果為:-XX:MetaspaceSize=21807104
jinfo -flag MaxMetaspaceSize 1234 #結(jié)果為:-XX:MaxMetaspaceSize=18446744073709547520
干貨:MetaspaceSize為觸發(fā)FullGC的閾值,默認(rèn)約為21M,如做了配置,最小閾值為自定義配置大小??臻g使用達(dá)到閾值,觸發(fā)FullGC,同時(shí)對(duì)該值擴(kuò)大。當(dāng)然如果元空間實(shí)際使用小于閾值,在GC的時(shí)候也會(huì)對(duì)該值縮小。
MaxMetaspaceSize為元空間的最大值,如果設(shè)置太小,可能會(huì)導(dǎo)致頻繁FullGC,甚至OOM。
5. JVM參數(shù)配置指南
前面三個(gè)部分對(duì)JVM進(jìn)行了整體的了解,接下來(lái)是本文的重點(diǎn)。
-XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=256M -Xms256m -Xmx256m
文章看下來(lái)上面這段配置的意思很簡(jiǎn)單,設(shè)置元空間的初始值和最大值,設(shè)置堆空間的初始值和最大值。
為什么MetaspaceSize要設(shè)置為128M?為什么堆內(nèi)存初始值Xms設(shè)置為256M而不是512M?
按照J(rèn)ava官方的指導(dǎo)
- Java堆大小設(shè)置,Xms 和 Xmx設(shè)置為老年代存活對(duì)象的3-4倍,即FullGC之后的老年代內(nèi)存占用的3-4倍
- MaxPermSize(元空間)設(shè)置為老年代存活對(duì)象的1.2-1.5倍。
- 年輕代Xmn的設(shè)置為老年代存活對(duì)象的1-1.5倍。
- 老年代的內(nèi)存大小設(shè)置為老年代存活對(duì)象的2-3倍。
5. JVM監(jiān)控jstat
可以讓系統(tǒng)運(yùn)行一段時(shí)間后查看系統(tǒng)的各個(gè)指標(biāo),然后在進(jìn)行配置。如下用jstat工具查看jvm的情況
jstat -gc 12345
###
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
13824.0 22528.0 13377.0 0.0 548864.0 535257.2 113152.0 46189.3 73984.0 71119.8 9728.0 9196.2 14 0.259 3 0.287 0.546
OU表示老年代所占用的內(nèi)存為 46189.3 K(大約45M);那么jvm相應(yīng)的配置參數(shù)應(yīng)該做如下修改
-XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=64M -Xms180m -Xmx180m
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
springboot讀取resource配置文件生成容器對(duì)象的示例代碼
這篇文章主要介紹了springboot讀取resource配置文件生成容器對(duì)象的示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07Spring MVC注解式開(kāi)發(fā)示例完整過(guò)程
這篇文章主要介紹了Spring MVC注解式開(kāi)發(fā)示例完整過(guò)程,MVC注解式開(kāi)發(fā)即處理器基于注解的類(lèi)開(kāi)發(fā),對(duì)于每一個(gè)定義的處理器,無(wú)需在xml中注冊(cè),只需在代碼中通過(guò)對(duì)類(lèi)與方法的注解,即可完成注冊(cè)2023-02-02Spring-MVC異步請(qǐng)求之Servlet異步處理
這篇文章主要介紹了Spring-MVC異步請(qǐng)求之Servlet異步處理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01Spring中ContextLoaderListener監(jiān)聽(tīng)詳解
這篇文章主要介紹了Spring中ContextLoaderListener監(jiān)聽(tīng)詳解,SpringMVC啟動(dòng)時(shí)會(huì)啟動(dòng)WebApplicationContext類(lèi)型的容器,并且會(huì)調(diào)用之前分析的refresh方法,需要的朋友可以參考下2024-01-01Spring Cloud Alibaba整合Sentinel的實(shí)現(xiàn)步驟
這篇文章主要介紹了Spring Cloud Alibaba整合Sentinel的實(shí)現(xiàn)步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10JAVA 實(shí)現(xiàn)延遲隊(duì)列的方法
這篇文章主要介紹了JAVA 實(shí)現(xiàn)延遲隊(duì)列的方法,文中講解非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06SpringBoot?SpringSecurity?JWT實(shí)現(xiàn)系統(tǒng)安全策略詳解
Spring?Security是Spring的一個(gè)核心項(xiàng)目,它是一個(gè)功能強(qiáng)大且高度可定制的認(rèn)證和訪問(wèn)控制框架。它提供了認(rèn)證和授權(quán)功能以及抵御常見(jiàn)的攻擊,它已經(jīng)成為保護(hù)基于spring的應(yīng)用程序的事實(shí)標(biāo)準(zhǔn)2022-11-11