国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

JVM常用調(diào)優(yōu)策略

這篇具有很好參考價(jià)值的文章主要介紹了JVM常用調(diào)優(yōu)策略。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1、JVM調(diào)優(yōu)的核心關(guān)注指標(biāo)

調(diào)優(yōu)之前首先我們要知道怎樣才算是“優(yōu)”,不能籠統(tǒng)的說我的程序性能很好,所以就需要有一個(gè)具體的指標(biāo)來衡量性能情況,而在JVM里面衡量性能兩個(gè)指標(biāo)分別“吞吐量”和“停頓時(shí)間”。

  • 吞吐量:程序運(yùn)行過程中執(zhí)行兩種任務(wù),分別是執(zhí)行業(yè)務(wù)代碼和進(jìn)行垃圾回收,吞吐量大意就是說程序運(yùn)行業(yè)務(wù)代碼的時(shí)間越多程序的吞吐量就越高,其計(jì)算公式 ,吞吐量 = CPU在用戶應(yīng)用程序運(yùn)行的時(shí)間 / (CPU在用戶應(yīng)用程序運(yùn)行的時(shí)間 + CPU垃圾回收的時(shí)間),一般而言GC 的吞吐量不能低于 95%。
  • 停頓時(shí)間:?因?yàn)镴VM進(jìn)行垃圾回收的時(shí)候,某些階段必須要停止業(yè)務(wù)線程專心進(jìn)行垃圾收集,停頓時(shí)間就是指JVM停止業(yè)務(wù)線程而去進(jìn)行垃圾收集的這段時(shí)長,停頓時(shí)間越長就意味著用戶線程等待的時(shí)間越長,停頓時(shí)間會(huì)直接影響用戶使用系統(tǒng)的體驗(yàn)。
  • 垃圾回收頻率:通常來說垃圾回收頻率是越低越好,垃圾收集的過程是非常占用CPU資源的,資源有限如果垃圾收集占用的資源越多那么意味著其他事情所用的資源會(huì)減少,系統(tǒng)所能做的事情也會(huì)越少。當(dāng)然也不能一味的追求GC次數(shù)減少,GC次數(shù)減少了有可能就會(huì)使得單次GC的時(shí)間變長,那么就可能會(huì)增加單次GC的“停頓時(shí)長”,所以需要在這兩者之間做一些平衡。

2、如果獲得這些指標(biāo)?

在項(xiàng)目啟動(dòng)的時(shí)候 增加下列參數(shù)來收集GC日志,然后通過第三方的日志分析工具(GCesay:https://gceasy.io/)分析收集到的GC日志來得到吞吐量、停頓時(shí)間相關(guān)的統(tǒng)計(jì)數(shù)據(jù)。

 java  
 -XX:+PrintGCDetails -XX:+PrintGCDateStamps 
 -XX:+UseGCLogFileRotation 
 -XX:+PrintHeapAtGC -XX:NumberOfGCLogFiles=5  
 -XX:GCLogFileSize=20M    
 -Xloggc:/opt/ard-user-gc-%t.log  
 -jar abg-user-1.0-SNAPSHOT.jar 
 -Xloggc:/opt/app/ard-user/ard-user-gc-%t.log   設(shè)置日志目錄和日志名稱
 -XX:+UseGCLogFileRotation           開啟滾動(dòng)生成日志
 -XX:NumberOfGCLogFiles=5            滾動(dòng)GC日志文件數(shù),默認(rèn)0,不滾動(dòng)
 -XX:GCLogFileSize=20M               GC文件滾動(dòng)大小,需開啟UseGCLogFileRotation
 -XX:+PrintGCDetails                 開啟記錄GC日志詳細(xì)信息(包括GC類型、各個(gè)操作使用的時(shí)間),并且在程序運(yùn)行結(jié)束打印出JVM的內(nèi)存占用情況
 -XX:+ PrintGCDateStamps             記錄系統(tǒng)的GC時(shí)間           
 -XX:+PrintGCCause                   產(chǎn)生GC的原因(默認(rèn)開啟)

3、確定調(diào)優(yōu)的標(biāo)準(zhǔn)

JVM調(diào)優(yōu)也,沒有萬能的公式和標(biāo)準(zhǔn),因?yàn)槊總€(gè)人所面對(duì)的場景是不一樣。要想調(diào)整到最優(yōu)的性能,其實(shí)首先要確認(rèn)的是自己的需求目標(biāo)是什么,需要做的就是根據(jù)這個(gè)目標(biāo)去慢慢的調(diào)整各項(xiàng)指標(biāo)從而達(dá)到一個(gè)最佳的平衡點(diǎn)。

3.1 吞吐量和停頓時(shí)間的選擇

調(diào)優(yōu)前首先要確定大方向,是選擇基于吞吐量調(diào)優(yōu)、還是停頓時(shí)間調(diào)優(yōu),哪個(gè)是你的硬性指標(biāo),這個(gè)硬性標(biāo)準(zhǔn)就是指導(dǎo)你進(jìn)行調(diào)優(yōu)的原則。

  1. 如果你的應(yīng)用和用戶沒有什么交互,完全不需要關(guān)注用戶體驗(yàn),那么你的硬性標(biāo)準(zhǔn)就是不顧一切的提升吞吐量,達(dá)到程序性能的最優(yōu)。
  2. 相反如果你的應(yīng)用是頻繁和用戶進(jìn)行交互的,那么提升用戶體驗(yàn)就是一個(gè)非常重要的指標(biāo)了,這個(gè)時(shí)候你的原則就是在用戶能忍受卡頓時(shí)間(停頓時(shí)間)范圍之內(nèi),來調(diào)整指標(biāo)來找到停頓時(shí)間和吞吐量的一個(gè)平衡值 。

舉個(gè)不是很恰當(dāng)?shù)兄谀憷斫膺@個(gè)思路的例子:

如果用戶在點(diǎn)擊一個(gè)功能之后500ms之內(nèi)沒有返回,就會(huì)使用戶焦慮,那么500ms就是影響用戶體驗(yàn)的一個(gè)標(biāo)準(zhǔn)了。如果你的業(yè)務(wù)代碼執(zhí)行到返回的時(shí)間需要運(yùn)行的時(shí)間為400ms,那么意味著垃圾回收的停頓的時(shí)間必須控制在100ms之內(nèi)才對(duì)用戶體驗(yàn)沒有影響。 所以這個(gè)時(shí)候你的調(diào)優(yōu)硬性標(biāo)準(zhǔn)就是把停頓時(shí)間控制在100ms之內(nèi),然后在這個(gè)時(shí)間范圍的基礎(chǔ)上去調(diào)整JVM參數(shù)讓吞吐量越高越好。
有了指導(dǎo)原則后,我們就需要在這兩個(gè)指標(biāo)上進(jìn)行平衡達(dá)到最優(yōu)值了,比如這個(gè)時(shí)候如果有兩組指標(biāo),第一組:停頓時(shí)間為80ms,吞吐量為92,第二組停頓時(shí)間為98ms,吞吐量為98,那么相對(duì)而言第二組指標(biāo)是一個(gè)合適調(diào)優(yōu)結(jié)果,因?yàn)樗捶?00ms停頓時(shí)間的原則,又將吞吐量最大化了。


4、常用調(diào)優(yōu)策略

4.1 選擇合適的垃圾回收器

  • CPU單核,那么毫無疑問Serial 垃圾收集器是你唯一的選擇。
  • CPU多核,關(guān)注吞吐量 ,那么選擇PS+PO組合。
  • CPU多核,關(guān)注用戶停頓時(shí)間,JDK版本1.6或者1.7,那么選擇CMS。
  • CPU多核,關(guān)注用戶停頓時(shí)間,JDK1.8及以上,JVM可用內(nèi)存6G以上,那么選擇G1。

參數(shù)配置:

 //設(shè)置Serial垃圾收集器(新生代)
 開啟:-XX:+UseSerialGC
 
 //設(shè)置PS+PO,新生代使用功能Parallel Scavenge 老年代將會(huì)使用Parallel Old收集器
 開啟 -XX:+UseParallelOldGC
 
 //CMS垃圾收集器(老年代)
 開啟 -XX:+UseConcMarkSweepGC
 
 //設(shè)置G1垃圾收集器
 開啟 -XX:+UseG1GC

4.2 增加內(nèi)存大小

現(xiàn)象:垃圾收集頻率非常頻繁。
原因:如果內(nèi)存太小,就會(huì)導(dǎo)致頻繁的需要進(jìn)行垃圾收集才能釋放出足夠的空間來創(chuàng)建新的對(duì)象,所以增加堆內(nèi)存大小的效果是非常顯而易見的。
注意:如果垃圾收集次數(shù)非常頻繁,但是每次能回收的對(duì)象非常少,那么這個(gè)時(shí)候并非內(nèi)存太小,而可能是內(nèi)存泄漏導(dǎo)致對(duì)象無法回收,從而造成頻繁GC。

參數(shù)配置:

 //設(shè)置堆初始值
 指令1:-Xms2g
 指令2:-XX:InitialHeapSize=2048m
 
 //設(shè)置堆區(qū)最大值
 指令1:`-Xmx2g` 
 指令2: -XX:MaxHeapSize=2048m
 
 //新生代內(nèi)存配置
 指令1:-Xmn512m
 指令2:-XX:MaxNewSize=512m

4.3 設(shè)置符合預(yù)期的停頓時(shí)間

現(xiàn)象:程序間接性的卡頓
原因:如果沒有確切的停頓時(shí)間設(shè)定,垃圾收集器以吞吐量為主,那么垃圾收集時(shí)間就會(huì)不穩(wěn)定。
注意:不要設(shè)置不切實(shí)際的停頓時(shí)間,單次時(shí)間越短也意味著需要更多的GC次數(shù)才能回收完原有數(shù)量的垃圾.

參數(shù)配置:

 //GC停頓時(shí)間,垃圾收集器會(huì)嘗試用各種手段達(dá)到這個(gè)時(shí)間
 -XX:MaxGCPauseMillis 

4.4 調(diào)整內(nèi)存區(qū)域大小比率

現(xiàn)象:某一個(gè)區(qū)域的GC頻繁,其他都正常。
原因:如果對(duì)應(yīng)區(qū)域空間不足,導(dǎo)致需要頻繁GC來釋放空間,在JVM堆內(nèi)存無法增加的情況下,可以調(diào)整對(duì)應(yīng)區(qū)域的大小比率。
注意:也許并非空間不足,而是因?yàn)閮?nèi)存泄漏造成內(nèi)存無法回收。從而導(dǎo)致GC頻繁。

參數(shù)配置:

 // survivor區(qū)和Eden區(qū)大小比率
 指令:-XX:SurvivorRatio=6  //S區(qū)和Eden區(qū)占新生代比率為1:6,兩個(gè)S區(qū)2:6
 
 // 新生代和老年代的占比
 -XX:NewRatio=4  //表示新生代:老年代 = 1:4 即老年代占整個(gè)堆的4/5;默認(rèn)值=2

4.5 調(diào)整對(duì)象升老年代的年齡

現(xiàn)象:老年代頻繁GC,每次回收的對(duì)象很多。
原因:如果新升代年齡小,新生代的對(duì)象很快就進(jìn)入老年代了,導(dǎo)致老年代對(duì)象變多,而這些對(duì)象其實(shí)在隨后的很短時(shí)間內(nèi)就可以回收,這時(shí)候可以調(diào)整對(duì)象的升級(jí)老年代的年齡,讓對(duì)象不那么容易進(jìn)入老年代解決老年代空間不足頻繁GC問題。
注意:增加了年齡之后,這些對(duì)象在新生代的時(shí)間會(huì)變長可能導(dǎo)致新生代的GC頻率增加,并且頻繁復(fù)制這些對(duì)象新生的GC時(shí)間也可能變長。

配置參數(shù):

 // 進(jìn)入老年代最小的GC年齡,年輕代對(duì)象轉(zhuǎn)換為老年代對(duì)象最小年齡值,默認(rèn)值7
 -XX:InitialTenuringThreshol=7 

4.6 調(diào)整大對(duì)象的標(biāo)準(zhǔn)

現(xiàn)象:老年代頻繁GC,每次回收的對(duì)象很多,而且單個(gè)對(duì)象的體積都比較大。
原因:如果大量的大對(duì)象直接分配到老年代,導(dǎo)致老年代容易被填滿而造成頻繁GC,可設(shè)置對(duì)象直接進(jìn)入老年代的標(biāo)準(zhǔn)。
注意:這些大對(duì)象進(jìn)入新生代后可能會(huì)使新生代的GC頻率和時(shí)間增加。

配置參數(shù):

 //新生代可容納的最大對(duì)象,大于則直接會(huì)分配到老年代,0代表沒有限制。
  -XX:PretenureSizeThreshold=1000000 

4.7 調(diào)整GC的觸發(fā)時(shí)機(jī)

現(xiàn)象:CMS,G1 經(jīng)常 Full GC,程序卡頓嚴(yán)重。
原因:G1和CMS 部分GC階段是并發(fā)進(jìn)行的,業(yè)務(wù)線程和垃圾收集線程一起工作,也就說明垃圾收集的過程中業(yè)務(wù)線程會(huì)生成新的對(duì)象,所以在GC的時(shí)候需要預(yù)留一部分內(nèi)存空間來容納新產(chǎn)生的對(duì)象,如果這個(gè)時(shí)候內(nèi)存空間不足以容納新產(chǎn)生的對(duì)象,那么JVM就會(huì)停止并發(fā)收集暫停所有業(yè)務(wù)線程(STW)來保證垃圾收集的正常運(yùn)行。這個(gè)時(shí)候可以調(diào)整GC觸發(fā)的時(shí)機(jī)(比如在老年代占用60%就觸發(fā)GC),這樣就可以預(yù)留足夠的空間來讓業(yè)務(wù)線程創(chuàng)建的對(duì)象有足夠的空間分配。
注意:提早觸發(fā)GC會(huì)增加老年代GC的頻率。

配置參數(shù):

 //使用多少比例的老年代后開始CMS收集,默認(rèn)是68%,如果頻繁發(fā)生SerialOld卡頓,應(yīng)該調(diào)小
 -XX:CMSInitiatingOccupancyFraction
 
 //G1混合垃圾回收周期中要包括的舊區(qū)域設(shè)置占用率閾值。默認(rèn)占用率為 65%
 -XX:G1MixedGCLiveThresholdPercent=65 

4.8 調(diào)整 JVM本地內(nèi)存大小

現(xiàn)象:GC的次數(shù)、時(shí)間和回收的對(duì)象都正常,堆內(nèi)存空間充足,但是報(bào)OOM
原因:?JVM除了堆內(nèi)存之外還有一塊堆外內(nèi)存,這片內(nèi)存也叫本地內(nèi)存,可是這塊內(nèi)存區(qū)域不足了并不會(huì)主動(dòng)觸發(fā)GC,只有在堆內(nèi)存區(qū)域觸發(fā)的時(shí)候順帶會(huì)把本地內(nèi)存回收了,而一旦本地內(nèi)存分配不足就會(huì)直接報(bào)OOM異常。
注意:?本地內(nèi)存異常的時(shí)候除了上面的現(xiàn)象之外,異常信息可能是OutOfMemoryError:Direct buffer memory。 解決方式除了調(diào)整本地內(nèi)存大小之外,也可以在出現(xiàn)此異常時(shí)進(jìn)行捕獲,手動(dòng)觸發(fā)GC(System.gc())。

配置參數(shù):

 XX:MaxDirectMemorySize

4.9 優(yōu)化業(yè)務(wù)代碼。

絕大部分的問題都出自于業(yè)務(wù)代碼本身的問題,在JVM調(diào)優(yōu)里面也不例外,要減少GC的頻率 其實(shí)業(yè)務(wù)代碼做一個(gè)很簡單的優(yōu)化就可以達(dá)到。

  1. 優(yōu)化代碼數(shù)據(jù), 比如我們?nèi)绻麡I(yè)務(wù)代碼中減少非必要的對(duì)象、字段、屬性,對(duì)象變少,體積變小,可以減少GC次數(shù)和時(shí)間問題。
  2. 提升方法的運(yùn)行效率,方法執(zhí)行完后產(chǎn)生的對(duì)象就可以釋放進(jìn)行回收了,方法運(yùn)行時(shí)間越長那么這些對(duì)象呆在堆內(nèi)存的時(shí)間就越久,內(nèi)存就越容易堆滿,GC的頻率就會(huì)增加。
  3. 避免內(nèi)存泄漏,?還有由于業(yè)務(wù)代碼的不合理導(dǎo)致的內(nèi)存泄露長期無法回收,這也是JVM最常見的問題。所以解決業(yè)務(wù)代碼的問題有時(shí)候遠(yuǎn)比上面的參數(shù)調(diào)優(yōu)要有效得多。

5、JVM調(diào)優(yōu)場景案例

5.1 場景一:網(wǎng)站流量瀏覽量暴增后,網(wǎng)站反應(yīng)頁面響很慢。

1、問題推測:在測試環(huán)境測速度比較快,但是一到生產(chǎn)就變慢,所以推測可能是因?yàn)槔占瘜?dǎo)致的業(yè)務(wù)線程停頓。

2、定位:為了確認(rèn)推測的正確性,在線上通過jstat -gc 指令 看到JVM進(jìn)行GC 次數(shù)頻率非常高,GC所占用的時(shí)間非常長,所以基本推斷就是因?yàn)镚C頻率非常高,所以導(dǎo)致業(yè)務(wù)線程經(jīng)常停頓,從而造成網(wǎng)頁反應(yīng)很慢。

3、解決方案:因?yàn)榫W(wǎng)頁訪問量很高,所以對(duì)象創(chuàng)建速度非???,導(dǎo)致堆內(nèi)存容易填滿從而頻繁GC,所以這里問題在于新生代內(nèi)存太小,所以這里可以增加JVM內(nèi)存就行了,所以初步從原來的2G內(nèi)存增加到16G內(nèi)存。

4、第二個(gè)問題:增加內(nèi)存后的確平常的請(qǐng)求比較快了,但是又出現(xiàn)了另外一個(gè)問題,就是不定期的會(huì)間斷性的卡頓,而且單次卡頓的時(shí)間要比之前要長很多。

5、問題推測:聯(lián)系到之前優(yōu)化加大了內(nèi)存,所以推測可能是因?yàn)閮?nèi)存加大了,從而導(dǎo)致單次GC的時(shí)間變長從而導(dǎo)致間接性的卡頓。

6、定位:還是通過jstat -gc?指令 查看到 的確FGC次數(shù)并不是很高,但是花費(fèi)在FGC上的時(shí)間是非常高的,根據(jù)GC日志 查看到單次FGC的時(shí)間有達(dá)到幾十秒的。

7、解決方案:?因?yàn)镴VM默認(rèn)使用的是PS+PO的組合,PS+PO垃圾標(biāo)記和收集階段都是STW,所以內(nèi)存加大了之后,需要進(jìn)行垃圾回收的時(shí)間就變長了,所以這里要想避免單次GC時(shí)間過長,所以需要更換并發(fā)類的收集器,因?yàn)楫?dāng)前的JDK版本為1.7,所以最后選擇CMS垃圾收集器,根據(jù)之前垃圾收集情況設(shè)置了一個(gè)預(yù)期的停頓的時(shí)間,上線后網(wǎng)站再也沒有了卡頓問題。

5.2 場景二:后臺(tái)導(dǎo)出數(shù)據(jù)引發(fā)的OOM

問題描述:公司的后臺(tái)系統(tǒng),偶發(fā)性的引發(fā)OOM異常,堆內(nèi)存溢出。

1、因?yàn)槭桥及l(fā)性的,所以第一次簡單的認(rèn)為就是堆內(nèi)存不足導(dǎo)致,所以單方面的加大了堆內(nèi)存從4G調(diào)整到8G。

2、但是問題依然沒有解決,只能從堆內(nèi)存信息下手,通過開啟了-XX:+HeapDumpOnOutOfMemoryError參數(shù) 獲得堆內(nèi)存的dump文件。

3、VisualVM 對(duì) 堆dump文件進(jìn)行分析,通過VisualVM查看到占用內(nèi)存最大的對(duì)象是String對(duì)象,本來想跟蹤著String對(duì)象找到其引用的地方,但dump文件太大,跟蹤進(jìn)去的時(shí)候總是卡死,而String對(duì)象占用比較多也比較正常,最開始也沒有認(rèn)定就是這里的問題,于是就從線程信息里面找突破點(diǎn)。

4、通過線程進(jìn)行分析,先找到了幾個(gè)正在運(yùn)行的業(yè)務(wù)線程,然后逐一跟進(jìn)業(yè)務(wù)線程看了下代碼,發(fā)現(xiàn)有個(gè)引起我注意的方法,導(dǎo)出訂單信息。

5、因?yàn)橛唵涡畔?dǎo)出這個(gè)方法可能會(huì)有幾萬的數(shù)據(jù)量,首先要從數(shù)據(jù)庫里面查詢出來訂單信息,然后把訂單信息生成excel,這個(gè)過程會(huì)產(chǎn)生大量的String對(duì)象。

6、為了驗(yàn)證自己的猜想,于是準(zhǔn)備登錄后臺(tái)去測試下,結(jié)果在測試的過程中發(fā)現(xiàn)到處訂單的按鈕前端居然沒有做點(diǎn)擊后按鈕置灰交互事件,結(jié)果按鈕可以一直點(diǎn),因?yàn)閷?dǎo)出訂單數(shù)據(jù)本來就非常慢,使用的人員可能發(fā)現(xiàn)點(diǎn)擊后很久后頁面都沒反應(yīng),結(jié)果就一直點(diǎn),結(jié)果就大量的請(qǐng)求進(jìn)入到后臺(tái),堆內(nèi)存產(chǎn)生了大量的訂單對(duì)象和EXCEL對(duì)象,而且方法執(zhí)行非常慢,導(dǎo)致這一段時(shí)間內(nèi)這些對(duì)象都無法被回收,所以最終導(dǎo)致內(nèi)存溢出。

7、知道了問題就容易解決了,最終沒有調(diào)整任何JVM參數(shù),只是在前端的導(dǎo)出訂單按鈕上加上了置灰狀態(tài),等后端響應(yīng)之后按鈕才可以進(jìn)行點(diǎn)擊,然后減少了查詢訂單信息的非必要字段來減少生成對(duì)象的體積,然后問題就解決了。

5.3 場景三:單個(gè)緩存數(shù)據(jù)過大導(dǎo)致的系統(tǒng)CPU飚高。

1、系統(tǒng)發(fā)布后發(fā)現(xiàn)CPU一直飚高到600%,發(fā)現(xiàn)這個(gè)問題后首先要做的是定位到是哪個(gè)應(yīng)用占用CPU高,通過top 找到了對(duì)應(yīng)的一個(gè)java應(yīng)用占用CPU資源600%。

2、如果是應(yīng)用的CPU飚高,那么基本上可以定位可能是鎖資源競爭,或者是頻繁GC造成的。

3、所以準(zhǔn)備首先從GC的情況排查,如果GC正常的話再從線程的角度排查,首先使用jstat -gc PID 指令打印出GC的信息,結(jié)果得到得到的GC 統(tǒng)計(jì)信息有明顯的異常,應(yīng)用在運(yùn)行了才幾分鐘的情況下GC的時(shí)間就占用了482秒,那么問這很明顯就是頻繁GC導(dǎo)致的CPU飚高。

4、定位到了是GC的問題,那么下一步就是找到頻繁GC的原因了,所以可以從兩方面定位了,可能是哪個(gè)地方頻繁創(chuàng)建對(duì)象,或者就是有內(nèi)存泄露導(dǎo)致內(nèi)存回收不掉。

5、根據(jù)這個(gè)思路決定把堆內(nèi)存信息dump下來看一下,使用jmap -dump 指令把堆內(nèi)存信息dump下來(堆內(nèi)存空間大的慎用這個(gè)指令否則容易導(dǎo)致會(huì)影響應(yīng)用,因?yàn)槲覀兊亩褍?nèi)存空間才2G所以也就沒考慮這個(gè)問題了)。

6、把堆內(nèi)存信息dump下來后,就使用visualVM進(jìn)行離線分析了,首先從占用內(nèi)存最多的對(duì)象中查找,結(jié)果排名第三看到一個(gè)業(yè)務(wù)VO占用堆內(nèi)存約10%的空間,很明顯這個(gè)對(duì)象是有問題的。

7、通過業(yè)務(wù)對(duì)象找到了對(duì)應(yīng)的業(yè)務(wù)代碼,通過代碼的分析找到了一個(gè)可疑之處,這個(gè)業(yè)務(wù)對(duì)象是查看新聞資訊信息生成的對(duì)象,由于想提升查詢的效率,所以把新聞資訊保存到了redis緩存里面,每次調(diào)用資訊接口都是從緩存里面獲取。

8、把新聞保存到redis緩存里面這個(gè)方式是沒有問題的,有問題的是新聞的50000多條數(shù)據(jù)都是保存在一個(gè)key里面,這樣就導(dǎo)致每次調(diào)用查詢新聞接口都會(huì)從redis里面把50000多條數(shù)據(jù)都拿出來,再做篩選分頁拿出10條返回給前端。50000多條數(shù)據(jù)也就意味著會(huì)產(chǎn)生50000多個(gè)對(duì)象,每個(gè)對(duì)象280個(gè)字節(jié)左右,50000個(gè)對(duì)象就有13.3M,這就意味著只要查看一次新聞信息就會(huì)產(chǎn)生至少13.3M的對(duì)象,那么并發(fā)請(qǐng)求量只要到10,那么每秒鐘都會(huì)產(chǎn)生133M的對(duì)象,而這種大對(duì)象會(huì)被直接分配到老年代,這樣的話一個(gè)2G大小的老年代內(nèi)存,只需要幾秒就會(huì)塞滿,從而觸發(fā)GC。

9、知道了問題所在后那么就容易解決了,問題是因?yàn)閱蝹€(gè)緩存過大造成的,那么只需要把緩存減小就行了,這里只需要把緩存以頁的粒度進(jìn)行緩存就行了,每個(gè)key緩存10條作為返回給前端1頁的數(shù)據(jù),這樣的話每次查詢新聞信息只會(huì)從緩存拿出10條數(shù)據(jù),就避免了此問題的 產(chǎn)生。

5.4 場景四:CPU經(jīng)常100% 問題定位思路。

問題分析:CPU高一定是某個(gè)程序長期占用了CPU資源。

1、所以先需要找出那個(gè)進(jìn)行占用CPU高。

 top  列出系統(tǒng)各個(gè)進(jìn)程的資源占用情況。

2、然后根據(jù)找到對(duì)應(yīng)進(jìn)行里哪個(gè)線程占用CPU高。

 top -Hp 進(jìn)程ID   列出對(duì)應(yīng)進(jìn)程里面的線程占用資源情況

3、找到對(duì)應(yīng)線程ID后,再打印出對(duì)應(yīng)線程的堆棧信息

 printf "%x\n"  PID    把線程ID轉(zhuǎn)換為16進(jìn)制。
 jstack PID 打印出進(jìn)程的所有線程信息,從打印出來的線程信息中找到上一步轉(zhuǎn)換為16進(jìn)制的線程ID對(duì)應(yīng)的線程信息。

4、最后根據(jù)線程的堆棧信息定位到具體業(yè)務(wù)方法,從代碼邏輯中找到問題所在。

 查看是否有線程長時(shí)間的watting 或blocked
 如果線程長期處于watting狀態(tài)下, 關(guān)注watting on xxxxxx,說明線程在等待這把鎖,然后根據(jù)鎖的地址找到持有鎖的線程。

5.5 場景五:內(nèi)存飚高問題定位思路。

分析:?內(nèi)存飚高如果是發(fā)生在java進(jìn)程上,一般是因?yàn)閯?chuàng)建了大量對(duì)象所導(dǎo)致,持續(xù)飚高說明垃圾回收跟不上對(duì)象創(chuàng)建的速度,或者內(nèi)存泄漏導(dǎo)致對(duì)象無法回收。

1、觀察垃圾回收的情況

 jstat -gc PID 1000 查看GC次數(shù),時(shí)間等信息,每隔一秒打印一次。
  
 jmap -histo PID | head -20   查看堆內(nèi)存占用空間最大的前20個(gè)對(duì)象類型,可初步查看是哪個(gè)對(duì)象占用了內(nèi)存。

如果每次GC次數(shù)頻繁,而且每次回收的內(nèi)存空間也正常,那說明是因?yàn)閷?duì)象創(chuàng)建速度快導(dǎo)致內(nèi)存一直占用很高;如果每次回收的內(nèi)存非常少,那么很可能是因?yàn)閮?nèi)存泄露導(dǎo)致內(nèi)存一直無法被回收。

2、導(dǎo)出堆內(nèi)存文件快照

 jmap -dump:live,format=b,file=/home/myheapdump.hprof PID  dump堆內(nèi)存信息到文件。

3、使用visualVM對(duì)dump文件進(jìn)行離線分析,找到占用內(nèi)存高的對(duì)象,再找到創(chuàng)建該對(duì)象的業(yè)務(wù)代碼位置,從代碼和業(yè)務(wù)場景中定位具體問題。文章來源地址http://www.zghlxwxcb.cn/news/detail-706908.html

到了這里,關(guān)于JVM常用調(diào)優(yōu)策略的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Java線上故障排查(CPU、磁盤、內(nèi)存、網(wǎng)絡(luò)、GC)+JVM性能調(diào)優(yōu)監(jiān)控工具+JVM常用參數(shù)和命令

    Java線上故障排查(CPU、磁盤、內(nèi)存、網(wǎng)絡(luò)、GC)+JVM性能調(diào)優(yōu)監(jiān)控工具+JVM常用參數(shù)和命令

    根據(jù)服務(wù)部署和項(xiàng)目架構(gòu),從如下幾個(gè)方面排查: (1)運(yùn)用服務(wù)器:排查內(nèi)存,cpu,請(qǐng)求數(shù)等; (2)文件圖片服務(wù)器:排查內(nèi)存,cpu,請(qǐng)求數(shù)等; (3)計(jì)時(shí)器服務(wù)器:排查內(nèi)存,cpu,請(qǐng)求數(shù)等; (4)redis服務(wù)器:排查內(nèi)存,cpu,連接數(shù)等; (5)db服務(wù)器:排查內(nèi)存,cpu,連接數(shù)

    2024年02月07日
    瀏覽(29)
  • JVM調(diào)優(yōu)常用的工具JPS、JMAP、JSTAT、JSTACK和JCMD的使用詳解

    JVM調(diào)優(yōu)常用的工具JPS、JMAP、JSTAT、JSTACK和JCMD的使用詳解

    查看PID信息 首先啟動(dòng)一個(gè)服務(wù) ?使用jps 和 jps -l 的區(qū)別,使用jps -l 能夠顯示出服務(wù)的名稱 ?熟悉JVM調(diào)優(yōu)中常用的工具JMAP、JSTAT和JSTACK JMAP、JSTAT和JSTACK是Java開發(fā)中常用的工具,用于分析和調(diào)試Java應(yīng)用程序。它們的使用場景如下: JMAP:JMAP用于生成Java堆轉(zhuǎn)儲(chǔ)快照,以便分析

    2024年02月03日
    瀏覽(14)
  • JVM監(jiān)控和調(diào)優(yōu)常用命令jps|jstat|jinfo|jmap|jhat|jstack實(shí)戰(zhàn)

    性能優(yōu)化 :通過JVM調(diào)優(yōu),可以提高Java應(yīng)用程序的性能,減少響應(yīng)時(shí)間,提高吞吐量,以更好地滿足用戶需求。性能優(yōu)化可以加快應(yīng)用程序的執(zhí)行速度,減少延遲,提高用戶體驗(yàn)。 內(nèi)存管理 :JVM負(fù)責(zé)管理Java應(yīng)用程序的內(nèi)存。正確的內(nèi)存管理可以避免內(nèi)存泄漏和內(nèi)存溢出等問

    2024年02月09日
    瀏覽(23)
  • JVM 8 調(diào)優(yōu)指南:如何進(jìn)行JVM調(diào)優(yōu),JVM調(diào)優(yōu)參數(shù)

    這篇文章將詳細(xì)介紹如何進(jìn)行JVM 8調(diào)優(yōu),包括JVM 8調(diào)優(yōu)參數(shù)及其應(yīng)用。此外,我將提供12個(gè)實(shí)用的代碼示例,每個(gè)示例都會(huì)結(jié)合JVM啟動(dòng)參數(shù)和Java代碼。 本文已收錄于,我的技術(shù)網(wǎng)站 ddkk.com,有大廠完整面經(jīng),工作技術(shù),架構(gòu)師成長之路,等經(jīng)驗(yàn)分享 JVM調(diào)優(yōu)是指通過調(diào)整Java虛擬

    2024年01月21日
    瀏覽(23)
  • JVM 17 調(diào)優(yōu)指南:如何進(jìn)行JVM調(diào)優(yōu),JVM調(diào)優(yōu)參數(shù)

    在這篇文章中,我會(huì)詳細(xì)介紹JVM調(diào)優(yōu)的概念、重要性和具體的JVM調(diào)優(yōu)參數(shù)。此外,我將提供12個(gè)實(shí)用的代碼示例,每個(gè)示例都會(huì)包含JVM調(diào)優(yōu)參數(shù)和相應(yīng)的Java代碼。 本文已收錄于,我的技術(shù)網(wǎng)站 ddkk.com,有大廠完整面經(jīng),工作技術(shù),架構(gòu)師成長之路,等經(jīng)驗(yàn)分享 JVM調(diào)優(yōu)是調(diào)整

    2024年02月02日
    瀏覽(31)
  • JVM 11 調(diào)優(yōu)指南:如何進(jìn)行JVM調(diào)優(yōu),JVM調(diào)優(yōu)參數(shù)

    JVM 11的優(yōu)化指南:如何進(jìn)行JVM調(diào)優(yōu),以及JVM調(diào)優(yōu)參數(shù)有哪些”這篇文章將包含JVM 11調(diào)優(yōu)的核心概念、重要性、調(diào)優(yōu)參數(shù),并提供12個(gè)實(shí)用的代碼示例,每個(gè)示例都會(huì)結(jié)合JVM調(diào)優(yōu)參數(shù)和Java代碼 本文已收錄于,我的技術(shù)網(wǎng)站 ddkk.com,有大廠完整面經(jīng),工作技術(shù),架構(gòu)師成長之路,

    2024年01月16日
    瀏覽(15)
  • JVM 21 的調(diào)優(yōu)指南:如何進(jìn)行JVM調(diào)優(yōu),JVM調(diào)優(yōu)參數(shù)

    聊聊關(guān)于JVM 21的優(yōu)化指南。這篇文章將會(huì)深入探討如何進(jìn)行JVM調(diào)優(yōu),介紹一些關(guān)鍵的JVM調(diào)優(yōu)參數(shù),并提供12個(gè)實(shí)用的代碼示例。由于篇幅較長,我會(huì)分幾個(gè)部分來詳細(xì)講解,之前寫的也有33篇系列教程JVM調(diào)優(yōu)實(shí)戰(zhàn)打擊也可以去圍觀。 JVM(Java虛擬機(jī))調(diào)優(yōu)是一個(gè)復(fù)雜但重要的任

    2024年01月24日
    瀏覽(23)
  • JVM實(shí)戰(zhàn)(19)——JVM調(diào)優(yōu)工具概述

    JVM實(shí)戰(zhàn)(19)——JVM調(diào)優(yōu)工具概述

    作者簡介:大家好,我是smart哥,前中興通訊、美團(tuán)架構(gòu)師,現(xiàn)某互聯(lián)網(wǎng)公司CTO 聯(lián)系qq:184480602,加我進(jìn)群,大家一起學(xué)習(xí),一起進(jìn)步,一起對(duì)抗互聯(lián)網(wǎng)寒冬 學(xué)習(xí)必須往深處挖,挖的越深,基礎(chǔ)越扎實(shí)! 階段1、深入多線程 階段2、深入多線程設(shè)計(jì)模式 階段3、深入juc源碼解析

    2024年01月18日
    瀏覽(20)
  • JVM-JVM調(diào)優(yōu)基礎(chǔ)(理論)

    JVM-JVM調(diào)優(yōu)基礎(chǔ)(理論)

    申明:文章內(nèi)容是本人學(xué)習(xí)極客時(shí)間課程所寫,作為筆記進(jìn)行記錄,文字和圖片基本來源于課程資料,在某些地方會(huì)插入一點(diǎn)自己的理解,未用于商業(yè)用途,侵刪。 原資料地址:課程資料 JVM參數(shù) 標(biāo)準(zhǔn)參數(shù) 定義:穩(wěn)定的參數(shù)不會(huì)隨著Java版本的變化而變化。通常以 短橫線開頭

    2024年02月19日
    瀏覽(20)
  • JVM調(diào)優(yōu)(10)JVM的運(yùn)行時(shí)數(shù)據(jù)區(qū)

    JVM調(diào)優(yōu)(10)JVM的運(yùn)行時(shí)數(shù)據(jù)區(qū)

    對(duì)于 C C++ 來說,在內(nèi)存管理領(lǐng)域,JVM既擁有最高的權(quán)利,但是同時(shí)他們又是從事最基礎(chǔ)工作的勞動(dòng)人員,因?yàn)樗麄儞?dān)負(fù)著每一個(gè)對(duì)象從開始到結(jié)束的維護(hù)責(zé)任。而對(duì)于Java來說,再虛擬機(jī)自動(dòng)內(nèi)存管理的幫助下,不再需要為每一個(gè)new操作去分配內(nèi)存,不容易出現(xiàn)內(nèi)存泄漏和內(nèi)

    2024年02月07日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包