五月综合人人91天堂久久人妻|欧美成人精品H超碰超碰网站大全|在线国产三级片丁香综合无码视频|国产不卡23区www.AV在线|国产91色哟在亚洲无码强奸在线|岛国黄色视屏久久免费看黄片|91无码视频国产综合23p|日本人成在线春色激情69

衡水天泰計(jì)算機(jī)培訓(xùn)學(xué)校
JAVA技術(shù)

Java程序性能調(diào)優(yōu)步驟

來源:衡水北大青鳥 ????發(fā)布時間:2017-04-11 10:50 ????點(diǎn)擊:

1、性能調(diào)優(yōu)的步驟
 
1.1、衡量系統(tǒng)現(xiàn)狀
 
包括請求次數(shù)、響應(yīng)時間、資源消耗等;如:A系統(tǒng)目前95%的請求響應(yīng)為1s。
 
1.2、設(shè)定調(diào)優(yōu)目標(biāo)
 
根據(jù)用戶所能接受的響應(yīng)速度、系統(tǒng)現(xiàn)有的機(jī)器、所支撐的用戶量制定出來的,因此通常會設(shè)定調(diào)優(yōu)目標(biāo):95%的 請求在500ms內(nèi)返回。
 
1.3、尋找性能瓶頸
 
在【2、尋找性能瓶頸】會專門介紹。通常性能瓶頸的表像是:
 
1.3.1、資源消耗過多(CPU、文件IO、網(wǎng)絡(luò)IO、內(nèi)存)
 
1.3.2、外部系統(tǒng)處理不足(所調(diào)用的其他系統(tǒng)提供的功能——多數(shù)情況也是資源消耗過多、數(shù)據(jù)的操作響應(yīng)速度 不夠——根據(jù)數(shù)據(jù)庫SQL執(zhí)行速度、數(shù)據(jù)庫機(jī)器的IOPS、數(shù)據(jù)庫的Active Sessions等分析出來的)
 
1.3.3、程序代碼運(yùn)行效率不夠高,未充分使用資源或程序結(jié)構(gòu)不合理。
 
1.4、性能調(diào)優(yōu)
 
在后面的【3、性能調(diào)優(yōu)】會專門介紹
 
1.5、衡量是否達(dá)到目標(biāo)值
 
優(yōu)化部署后,達(dá)到目標(biāo)則結(jié)束,如果沒有則重復(fù)1.3、1.4步驟
 
2、尋找性能瓶頸
 
2.1、CPU消耗分析(top、pidstat等方式查看cpu消耗狀況;vmstat查看cpu的上下文切換、運(yùn)行隊(duì)列、利用率)
 
在Linux中,CPU消耗主要用于中斷、內(nèi)核以及用戶進(jìn)程的任務(wù)處理。優(yōu)先級為:中斷>內(nèi)核>用戶進(jìn)程。cpu消耗嚴(yán)重時,主要體現(xiàn)在:
 
①us—用戶進(jìn)程所占的%
 
過高的原因:1、線程一直處于可運(yùn)行(Runnable)狀態(tài),通常線程在執(zhí)行無阻塞、循環(huán)、正則或純粹的計(jì)算等動作引起的。2、頻繁的GC操作引起。如:每次請求需要分配較多內(nèi)存,當(dāng)訪問量高的時,就不斷的進(jìn)行GC,系統(tǒng)響應(yīng)速度下降。進(jìn)而造成堆積的請求更多,消耗內(nèi)存更嚴(yán)重,最嚴(yán)重的時候可能導(dǎo)致系統(tǒng) 不斷的進(jìn)行FULL GC??赏ㄟ^JVM內(nèi)存的消耗分析來查找原因。
 
可通過kill -3 [javapid]、jstack [pid] | grep 'nid=0X....' 的方式dump出應(yīng)用的java線程信息。通過轉(zhuǎn)換出的十六進(jìn)制的值就可以找到對應(yīng)的nid值的線程。該線程即為消耗CPU的線程。在采樣時多執(zhí)行幾次上訴過程,以確保找到真實(shí)的消耗CPU的線程。也可以通過intel vtune 這樣的商業(yè)軟件進(jìn)行分析
 
②sy—內(nèi)核線程所占的%
 
過高的原因:Linux花費(fèi)更多的時間在進(jìn)行線程切換。Java應(yīng)用造成這個原因是:因?yàn)閱恿说木€程比較多,且這些線程多數(shù)都處于不斷的阻塞(鎖等待、IO等待狀態(tài))和執(zhí)行狀態(tài)的變化過程,導(dǎo)致了操作系統(tǒng)需要不斷的切換執(zhí)行的線程。從而產(chǎn)生大量的上下文切換。
 
可通過kill -3 [javapid]、jstack -1 [javapid] 的方式dump出Java應(yīng)用線程信息,查看線程的狀態(tài)、鎖信息找出等待狀態(tài)或鎖競爭過多的線程。結(jié)合vvmstat 查看CPU消耗狀況。如cs(上下文切換)、sy等。
 
③ni—被nice命令改變優(yōu)先級的任務(wù)所占的%
 
④id—CPU空閑時間所占的%
 
⑤wa—執(zhí)行過程中等待io所占的%
 
⑥hi—硬件中斷所占的%
 
⑦si—軟件中斷所占的%
 
2.2、文件IO消耗分析(通過pidstat、iostat命令分析)
 
Java應(yīng)用造成io消耗嚴(yán)重主要是:
 
① 多個線程需要大量內(nèi)容寫入(如頻繁的log寫入)動作;
 
② 磁盤設(shè)備本身的處理速度慢
 
③ 文件系統(tǒng)慢
 
④ 操作的文件本身已經(jīng)很大
 
2.3、網(wǎng)絡(luò)IO消耗分析(通過sar命令,如需跟著TCP/IP通信過程的信息,則可通過tcpdump來進(jìn)行)
 
對于分布式Java應(yīng)用而言,網(wǎng)絡(luò)IO的消耗非常值得關(guān)注,尤其要注意網(wǎng)絡(luò)中斷是不是均衡地分配到各CPU的(通過cat/proc/interrupts命令查看)。對于網(wǎng)卡只分配到一個CPU的現(xiàn)象采用修改kernle方法(Google使用)、 采用支持MSI-X的網(wǎng)卡進(jìn)行修復(fù)。
 
由于沒辦法分析具體每個線程所消耗的網(wǎng)絡(luò)IO,因此當(dāng)網(wǎng)絡(luò)IO消耗高時,對于Java應(yīng)用而言只能對線程進(jìn)dump。
 
查找產(chǎn)生大量網(wǎng)絡(luò)IO操作的線程,這些線程的特征是讀取或?qū)懭刖W(wǎng)絡(luò)流,在Java網(wǎng)絡(luò)通信時,通常要對對象進(jìn)行序列
 
化為字節(jié)流,進(jìn)行發(fā)送,或者讀取。并反序列化為對象。這個過程要消耗JVM堆內(nèi)存,JVM對內(nèi)存通常是有限的。因此,Java應(yīng)用一般不會造成網(wǎng)絡(luò)IO消耗嚴(yán)重。
 
2.4、內(nèi)存消耗分析(vmstat、sar、pidstat、top)
 
目前Java應(yīng)用只有在創(chuàng)建線程和使用Direct ByteBuffer時才會操作JVM堆意外的內(nèi)存。對于JVM堆以外的內(nèi)存方面消耗,最為值得關(guān)注的是swpd的消耗以及物理內(nèi)存的消耗(可通過vmstat、sar、top、pidstat等方式查看swap和物理內(nèi)存的消耗狀況)。
 
2.5、消耗資源不多,在訪問量不大的情況。但程序執(zhí)行慢的原因,主要有3方面
 
① 鎖競爭激烈(如:數(shù)據(jù)庫連接池?cái)?shù),但是請求數(shù)多于連接池?cái)?shù))
 
② 未充分使用硬件資源(如:多核CPU,但程序卻采用單線程串行操作。)
 
③ 數(shù)據(jù)量增長(如:數(shù)據(jù)量的海量增長??蓪?shù)據(jù)庫的表拆分、庫拆分)
 
3、性能調(diào)優(yōu)
 
3.1JVM調(diào)優(yōu)
 
3.1.1、代大小調(diào)優(yōu)
 
① 避免新生代大小設(shè)置過小
 
1、避免頻繁進(jìn)行minor GC;2、可能導(dǎo)致minor GC對象直接進(jìn)入舊生代,占據(jù)舊生代空間,觸發(fā)FULL GC。
 
② 避免新生代設(shè)置過大
 
1、導(dǎo)致舊生代變小,可能導(dǎo)致FULL GC頻繁執(zhí)行;2、導(dǎo)致minor GC的耗時大幅度增加。
 
③ 避免survivor space過小或者過大
 
④ 根據(jù)具體代碼合理設(shè)置新生代的存活周期。
 
3.2.1、GC策略調(diào)優(yōu)
 
串行GC性能太差,因此實(shí)際應(yīng)用時主要是應(yīng)用并行和并發(fā)GC,大部分Web應(yīng)用在處理請求時設(shè)置了一個最大可同時處理的請求數(shù),當(dāng)超出此請求數(shù)時,會將之后的請求放 入等待隊(duì)列中,而這個等待隊(duì)列也限制了大小。當(dāng)?shù)却?duì)列滿了后,仍然有請求進(jìn)入,那么這些請求將丟棄,所有的請求又都是有超時限制度。
 
在這種情況下如果觸發(fā)了FULL GC造成應(yīng)用暫停時間較長的FULL GC,則有可能等這次FULL GC之后,應(yīng)用中很多請求就超時或者被丟棄了。
 
從上面可以看出,Web應(yīng)用非常需要一個對應(yīng)用造成暫停時間較短的GC,再加上大部分Web應(yīng)用的瓶頸都不在CPU上。因此對于Web應(yīng)用而言,在G1還不夠成熟的情況下,CMS GC是不錯的選擇。
 
3.2、程序調(diào)優(yōu)
 
3.2.1、CPU us高的解決方法
 
① 執(zhí)行線程無任何掛起動作,且一直運(yùn)行,導(dǎo)致CPU沒有機(jī)會去調(diào)度執(zhí)行其他的線程,造成線程餓死的現(xiàn)象。
 
解決:對這種線程的動作增加Thread.sleep(int),以釋放CPU的執(zhí)行權(quán),降低CPU的消耗。
 
原理:以損失單次執(zhí)行性能為代價,但由于降低了CPU消耗,在多線程的情況下,反而提高了平均性能。
 
② 狀態(tài)掃描。如:某線程要等其他線程改變了值才可以繼續(xù)執(zhí)行。
 
解決:改為采用wait/notify機(jī)制。
 
③ 循環(huán)次數(shù)過多、正則、計(jì)算等造成CPU us過高的情況。結(jié)合業(yè)務(wù)需求進(jìn)行調(diào)優(yōu)。code review是王道。
 
④ 頻繁GC造成us高的情況,通過JVM調(diào)優(yōu)或程序調(diào)優(yōu),降低GC的執(zhí)行次數(shù)。
 
3.2.2、CPU sy高的解決方法
 
① 線程運(yùn)行狀態(tài)經(jīng)常切換
 
解決:減少線程數(shù),且使用線程池
 
② 線程之間鎖競爭激烈
 
解決:盡可能降低鎖的競爭。
 
1、使用并發(fā)包中的類(java.util.concurrent.*)
 
2、使用Treiber算法
 
3、使用Michael-Scott非阻塞隊(duì)列算法(ConcurrentLinkedQueue就是典型的該算法的非阻塞隊(duì)列)
 
4、通常沒必要對整個方法加鎖,只對需要控制資源的地方做加鎖操作。
 
5、拆分鎖,把獨(dú)占鎖拆分為多把鎖,如:ConcurrentHashMap。很大程度上可以提高讀寫速度。
 
6、去除讀寫操作的互斥鎖
 
③ 較多網(wǎng)絡(luò)IO操作或者確實(shí)需要一些鎖競爭機(jī)制(如數(shù)據(jù)庫連接池),但為了能夠支持高的并發(fā)量,在Java應(yīng)用中又只能借助更多的線程來支撐。
 
解決:采用協(xié)程(Coroutine)來支持更高的并發(fā)量,避免并發(fā)量上漲之后造成CPU sy消耗嚴(yán)重、系統(tǒng)load迅速上漲和系統(tǒng)性能下降。
 
Java中目前主要可用于實(shí)現(xiàn)協(xié)程的框架為Kilim,早使用Kilim執(zhí)行一項(xiàng)任務(wù),并不創(chuàng)建Thread,而是采用Task。
 
3.3、文件IO消耗嚴(yán)重的解決方法
 
從程序角度看,造成文件IO消耗嚴(yán)重的原因主要是多個線程在寫大量的數(shù)據(jù)到同一文件。導(dǎo)致文件很快變大。
 
從而寫入速度越來越慢,并造成各線程激烈爭搶文件鎖,對于這種情況解決方法:
 
1、異步寫入文件;2、批量讀寫;3、限流;4、限制文件大小;5、盡可能采用緩沖區(qū)等方式來讀取文件內(nèi)容
 
3.4、網(wǎng)絡(luò)IO消耗嚴(yán)重的解決方法
 
從程序角度而言,造成網(wǎng)絡(luò)IO消耗嚴(yán)重的主要原因是同時需要發(fā)送或接受的包太多。可采用限流。限流通常是限制發(fā)送packet的頻率,從而在網(wǎng)絡(luò)IO消耗可接受的情況下來發(fā)送packet。
 
3.5、內(nèi)存消耗嚴(yán)重的情況
 
1、對JVM調(diào)優(yōu);2、代碼調(diào)優(yōu);
 
代碼調(diào)優(yōu)的方式:
 
① 釋放不必要的引用。如使用ThreadLocal,由于線程復(fù)用,ThreadLocal中存放的對象如未主動釋放的話,不會被GC。應(yīng)該在執(zhí)行完畢執(zhí)行ThreadLocal.set把對象清除,避免此有不必要的對象引用。
 
② 使用對象緩存池(享元模式)
 
③ 采用合理的緩存失效算法(FIFO、LRU、LFU等)
 
當(dāng)緩存池達(dá)到最大容量后,如果再加入新對象時采用FIFO、LRU、LFU等失效算法。
 
④ 對于占據(jù)內(nèi)存但又不是必須存在的對象使用SoftReference、WeakReference的方式進(jìn)行緩存。
 
SoftReference在內(nèi)存不夠用的情況進(jìn)行回收;WeakReference在FULL GC的情況下進(jìn)行回收。
 
3.6、對于資源消耗不多,但程序執(zhí)行慢的情況
 
3.6.1、鎖競爭激烈—見3.2.2②
 
3.6.2、未充分利用硬件資源。
 
① 未充分利用CPU
 
啟動多線程,但是單線程演變?yōu)槎嗑€程要加鎖,如:單線程計(jì)算,拆分為多線程分別計(jì)算,最后合并結(jié)果 如:JDK7的fork-join框架。
 
② 未充分使用內(nèi)存
 
數(shù)據(jù)庫緩存、耗時資源緩存(數(shù)據(jù)庫連接的創(chuàng)建、網(wǎng)絡(luò)連接的創(chuàng)建等)、頁面片段的緩存等。
 
結(jié)束語:從純粹的軟件角度調(diào)優(yōu)來講,充分而不過分的使用硬件資源,合理調(diào)整JVM以及合理使用JDK包是調(diào)優(yōu)的三大有效原則,調(diào)優(yōu)沒有“銀彈”。結(jié)合系統(tǒng)現(xiàn)狀和多嘗試不同的調(diào)優(yōu)策略是找到合適調(diào)優(yōu)方法的唯一途徑。
掃一掃 加關(guān)注 精彩資訊在這里!

技能認(rèn)證

OSTA技能證書,全國可查,真實(shí)可信

多項(xiàng)熱門專業(yè)自由選擇

豐富的專業(yè)課程設(shè)置,完全自由選擇

畢業(yè)推薦就業(yè)

5重就業(yè)保障體系,4項(xiàng)就業(yè)指導(dǎo)服務(wù)

學(xué)校地址

最方便的乘車路線

在線咨詢

來校講解答疑

在線咨詢

399入學(xué)禮包

報名熱線

0318-2888080

  • 版權(quán)所有2015~2021 衡水天泰計(jì)算機(jī)培訓(xùn)學(xué)校
    北大青鳥課程咨詢電話:0318-2888080 官方網(wǎng)址:m.076735.cn
    地址:河北省衡水市育才街與勝利交叉口南行200米路東 郵編:053000
    (網(wǎng)站客服咨詢QQ:3142643279)
  • 網(wǎng)站備案/許可證號:冀ICP備19035316號-1