记一次性能调优
說(shuō)到性能調(diào)優(yōu),給人的感覺(jué)往往都是修煉有成的專(zhuān)家干得事了,對(duì)于我們這些菜鳥(niǎo)還是想也不要想了,做好分內(nèi)事,不出現(xiàn)紕漏就OK了。對(duì)于這種觀點(diǎn)我表示嚴(yán)肅的否決!那想學(xué)習(xí)性能調(diào)優(yōu)的童鞋應(yīng)該從哪里下手呢?接下來(lái)就讓我們來(lái)談?wù)勱P(guān)于性能調(diào)優(yōu)你所忽視的一些常識(shí)。
一、代碼;
前文講過(guò)“華為Java編程軍規(guī),每季度代碼驗(yàn)收標(biāo)準(zhǔn)”這個(gè)標(biāo)準(zhǔn)是衡量代碼本身的缺陷,也是衡量一個(gè)研發(fā)人員本身的價(jià)值。代碼是性能調(diào)優(yōu)中的一粒分子,分子雖小但經(jīng)過(guò)上億次的分裂也會(huì)變成黑洞,所以代碼本身的缺陷也是我們性能調(diào)優(yōu)的主因之一。
1 軍規(guī)一:【避免在程序中使用魔鬼數(shù)字,必須用有意義的常量來(lái)標(biāo)識(shí)?!? 2 3 軍規(guī)二:【明確方法的功能,一個(gè)方法僅完成一個(gè)功能?!? 4 5 軍規(guī)三:【方法參數(shù)不能超過(guò)5個(gè)】 6 7 軍規(guī)四:【方法調(diào)用盡量不要返回null,取而代之以?huà)伋霎惓?#xff0c;或是返回特例對(duì)象(SPECIAL CASE object,SPECIAL CASE PATTERN);對(duì)于以集合或數(shù)組類(lèi)型作為返回值的方法,取而代之以空集合或0長(zhǎng)度數(shù)組?!? 8 9 軍規(guī)五:【在進(jìn)行數(shù)據(jù)庫(kù)操作或IO操作時(shí),必須確保資源在使用完畢后得到釋放,并且必須確保釋放操作在finally中進(jìn)行?!?10 11 軍規(guī)六:【異常捕獲不要直接catch (Exception ex) ,應(yīng)該把異常細(xì)分處理?!?12 13 軍規(guī)七:【對(duì)于if ? else if ?(后續(xù)可能有多個(gè)else if …)這種類(lèi)型的條件判斷,最后必須包含一個(gè)else分支,避免出現(xiàn)分支遺漏造成錯(cuò)誤;每個(gè)switch-case語(yǔ)句都必須保證有default,避免出現(xiàn)分支遺漏,造成錯(cuò)誤。】 14 15 軍規(guī)八:【覆寫(xiě)對(duì)象的equals()方法時(shí)必須同時(shí)覆寫(xiě)hashCode()方法。】 16 17 軍規(guī)九:【禁止循環(huán)中創(chuàng)建新線(xiàn)程,盡量使用線(xiàn)程池?!?18 19 軍規(guī)十:【在進(jìn)行精確計(jì)算時(shí)(例如:貨幣計(jì)算)避免使用float和double,浮點(diǎn)數(shù)計(jì)算都是不精確的,必須使用BigDecimal或?qū)⒏↑c(diǎn)數(shù)運(yùn)算轉(zhuǎn)換為整型運(yùn)算?!?
二、基準(zhǔn);
基準(zhǔn)環(huán)境,基準(zhǔn)負(fù)載和基準(zhǔn)指標(biāo),這是前提也是標(biāo)準(zhǔn)更是依據(jù)。沒(méi)有人能保證每次執(zhí)行的指標(biāo)就是真實(shí)有效的,今天提交個(gè)版本明天升級(jí)個(gè)環(huán)境這是我們不能容忍的。怎么才能基準(zhǔn)?什么又叫基準(zhǔn)?正式的標(biāo)準(zhǔn)的穩(wěn)定版本就是基準(zhǔn)。也只有基準(zhǔn)了,我們才能發(fā)現(xiàn)問(wèn)題。
三、硬件;
硬件環(huán)境的調(diào)整:主要是對(duì)系統(tǒng)運(yùn)行的硬件環(huán)境進(jìn)行調(diào)整,包括改變系統(tǒng)運(yùn)行的服務(wù)器、主機(jī)設(shè)備環(huán)境(改用具有更高性能的機(jī)器,或是調(diào)整某些服務(wù)器的物理內(nèi)存總量,CPU數(shù)量等),調(diào)整網(wǎng)絡(luò)環(huán)境(更換快速的網(wǎng)絡(luò)設(shè)備,或是采用更高帶寬的組網(wǎng)技術(shù))等。
四、系統(tǒng);
系統(tǒng)設(shè)置的調(diào)整:主要是對(duì)系統(tǒng)運(yùn)行的基礎(chǔ)平臺(tái)設(shè)置進(jìn)行調(diào)整,例如,根據(jù)應(yīng)用需要調(diào)整UNIX系統(tǒng)的核心參數(shù),調(diào)整數(shù)據(jù)庫(kù)的內(nèi)存池大小,調(diào)整應(yīng)用服務(wù)器使用的內(nèi)存大小,或是采用更高版本的JVM環(huán)境等;
注:推薦常有性能測(cè)試工具
? ? ? 性能測(cè)試工具:LR、kylinPET
? ? ? 系統(tǒng)監(jiān)控工具:nmon 或Linux(top sar)等自帶命令
? ? ? 強(qiáng)烈推薦:Spotlight.On.Oracle 非常不錯(cuò)的工具,誰(shuí)用誰(shuí)知道! ^^
五、軟件;
應(yīng)用框架的調(diào)整:主要是對(duì)應(yīng)用實(shí)現(xiàn)本身進(jìn)行調(diào)整,包括選用新的架構(gòu)、采用新的數(shù)據(jù)訪(fǎng)問(wèn)或是修改業(yè)務(wù)邏輯的實(shí)現(xiàn)方式等。
注:說(shuō)到架構(gòu)我現(xiàn)在正在研究阿里巴巴的Dubbo,有興趣的朋友可以一起探討探討。
“通過(guò)dubbo暴露接口調(diào)用方法,及基于zookeeper的dubbo涉及配置文件”http://www.cnblogs.com/Javame/p/3645481.html“基于ZooKeeper的Dubbo注冊(cè)中心”http://www.cnblogs.com/Javame/p/3632708.html “最近項(xiàng)目用到Dubbo框架,臨時(shí)抱佛腳分享一下共探討”http://www.cnblogs.com/Javame/p/3632473.html? ? ?六、再說(shuō)系統(tǒng)
ulimit -a 用來(lái)顯示當(dāng)前的各種用戶(hù)進(jìn)程限制。
Linux對(duì)于每個(gè)用戶(hù),系統(tǒng)限制其最大進(jìn)程數(shù)。為提高性能,可以根據(jù)設(shè)備資源情況,設(shè)置各linux 用戶(hù)的最大進(jìn)程數(shù),下面我把某linux用戶(hù)的最大進(jìn)程數(shù)設(shè)為10000個(gè):
對(duì)于需要做許多 socket 連接并使它們處于打開(kāi)狀態(tài)的 Java 應(yīng)用程序而言,最好通過(guò)使用 ulimit -n xx 修改每個(gè)進(jìn)程可打開(kāi)的文件數(shù),缺省值是 1024。
ulimit -n 4096 將每個(gè)進(jìn)程可以打開(kāi)的文件數(shù)目加大到4096,缺省為1024
其他建議設(shè)置成無(wú)限制(unlimited)的一些重要設(shè)置是:
暫時(shí)地,適用于通過(guò) ulimit 命令登錄 shell 會(huì)話(huà)期間。
永久地,通過(guò)將一個(gè)相應(yīng)的 ulimit 語(yǔ)句添加到由登錄 shell 讀取的文件中, 即特定于 shell 的用戶(hù)資源文件,如:
1)、解除 Linux 系統(tǒng)的最大進(jìn)程數(shù)和最大文件打開(kāi)數(shù)限制:
vi /etc/security/limits.conf# 添加如下的行* soft noproc 11000* hard noproc 11000* soft nofile 4100* hard nofile 4100?
??? 說(shuō)明:* 代表針對(duì)所有用戶(hù)
??? noproc 是代表最大進(jìn)程數(shù)
??? nofile 是代表最大文件打開(kāi)數(shù)
2)、讓 SSH 接受 Login 程式的登入,方便在 ssh 客戶(hù)端查看 ulimit -a 資源限制:
??? a、vi /etc/ssh/sshd_config
?????? 把 UserLogin 的值改為 yes,并把 # 注釋去掉
??? b、重啟 sshd 服務(wù):
?????? /etc/init.d/sshd restart
3)、修改所有 linux 用戶(hù)的環(huán)境變量文件:
/**************************************
有時(shí)候在程序里面需要打開(kāi)多個(gè)文件,進(jìn)行分析,系統(tǒng)一般默認(rèn)數(shù)量是1024,(用ulimit -a可以看到)對(duì)于正常使用是夠了,但是對(duì)于程序來(lái)講,就太少了。
修改2個(gè)文件。
1./etc/security/limits.confvi /etc/security/limits.conf加上:* soft nofile 8192* hard nofile 20480 2./etc/pam.d/loginsession required /lib/security/pam_limits.so?*********
??? 另外確保/etc/pam.d/system-auth文件有下面內(nèi)容
??? session required /lib/security/$ISA/pam_limits.so
??? 這一行確保系統(tǒng)會(huì)執(zhí)行這個(gè)限制。
***********
3.一般用戶(hù)的.bash_profile
#ulimit -n 1024
重新登陸ok
-------------
對(duì)于solaris
其實(shí)在系統(tǒng)里面有這樣一個(gè)命令ulimit,以下是ulimit -a執(zhí)行的結(jié)果:
time(seconds) unlimited file(blocks) unlimited data(kbytes) unlimited stack(kbytes) 8192 coredump(blocks) unlimited nofiles(descriptors) 1024 memory(kbytes) unlimited其中nofiles就是文件描述符的變量值,該值受rlim_fd_cur這個(gè)參數(shù)的影響,可以用ulimit -n number命令來(lái)修改。但不管怎么改,程序仍然不能突破fd=256的限制。在Solaris Tunable Parameters Reference Manua這本書(shū)里面能查到以下的資料:
A 32-bit program using standard I/O is limited to 256 file descriptors。
A 64-bit program using standard I/O can use up to 2 billion descriptors。
這也就是說(shuō)32位的程序是沒(méi)有辦法突破這個(gè)限制的,只有64位的程序才能使用高達(dá)2億個(gè)文件描述符,SUN的軟硬件在很早以前就實(shí)現(xiàn)了64位的架構(gòu),現(xiàn)在唯一要解決的就是將程序編譯成64位程序,為了生成64位程序,就必須要有64位的編譯器(其實(shí)不是這樣的),如果你去www.sunfreeware.com下載64位編譯器gcc,網(wǎng)站上沒(méi)有特別注明是64位的gcc,但是會(huì)有個(gè)意外的收獲,就是該軟件的說(shuō)明里面注明了只要在用gcc編譯的時(shí)候加上-m64的option就能生成64位程序了。
于是用gcc -m64去編譯生成一個(gè)64位程序后,用ulimit -n 102400將number of fd設(shè)成很大的情況下,所有問(wèn)題迎刃而解,再也不存在文件描述符不夠用的情況。
在/etc/system文件設(shè)置rlimi_fc_max和rlim_fd_cur格式如下:
* set hard limit on file descriptors
set rlim_fd_max = 4096
* set soft limit on file descriptors
set rlim_fd_cur = 1024
命令ulimit使用格式如下:
usage: ulimit [ -HSacdfnstv ] [ limit ]
ulimit -a是顯示各參數(shù)的設(shè)置值,ulimit -n是用來(lái)設(shè)置fd的最大值的。
*************************************************
修改文件描述符限制
Solaris有兩個(gè)參數(shù)控制進(jìn)程可打開(kāi)的文件描述符:rlim_fd_max,rlim_fd_cur。前者修改是個(gè)硬設(shè)置,修改需要權(quán)限,后者是個(gè)軟設(shè)置,用戶(hù)可以limit或者setrlimit() 修改,該值最大不能超過(guò)前者。一般我們?cè)?etc/system里修改這兩個(gè)參數(shù)
set rlim_fd_max = 65535
set rlim_fd_cur = 65535
==========================
ulimit 用于shell啟動(dòng)進(jìn)程所占用的資源。
可以使用該命令查看進(jìn)程占用資源的情況。
使用方法:ulimit [-acdfHlmnpsStvw] [size]
-H 設(shè)置硬件資源限制.
-S 設(shè)置軟件資源限制.
-a 顯示當(dāng)前所有的資源限制.
-c size:設(shè)置core文件的最大值.單位:blocks
-d size:設(shè)置數(shù)據(jù)段的最大值.單位:kbytes
-f size:設(shè)置創(chuàng)建文件的最大值.單位:blocks
-l size:設(shè)置在內(nèi)存中鎖定進(jìn)程的最大值.單位:kbytes
-m size:設(shè)置可以使用的常駐內(nèi)存的最大值.單位:kbytes
-n size:設(shè)置內(nèi)核可以同時(shí)打開(kāi)的文件描述符的最大值.單位:n
-p size:設(shè)置管道緩沖區(qū)的最大值.單位:kbytes
-s size:設(shè)置堆棧的最大值.單位:kbytes
-t size:設(shè)置CPU使用時(shí)間的最大上限.單位:seconds
-v size:設(shè)置虛擬內(nèi)存的最大值.單位:kbytes 5
1]在RH8的環(huán)境文件/etc/profile中,我們可以看到系統(tǒng)是如何配置ulimit的:
#grep ulimit /etc/profile
ulimit -S -c 0 > /dev/null 2>&1??? (輸出重定向,正常輸出和異常輸出都忽略)
這條語(yǔ)句設(shè)置了對(duì)軟件資源和對(duì)core文件大小的設(shè)置
2]如果我們想要對(duì)由shell創(chuàng)建的文件大小作些限制,如:
文件h的大小是150062字節(jié),而我們?cè)O(shè)定的創(chuàng)建文件的大小是512字節(jié)x100塊=51200字節(jié)
當(dāng)然系統(tǒng)就會(huì)根據(jù)你的設(shè)置生成了51200字節(jié)的newh文件.
Linux性能調(diào)優(yōu)基本策略設(shè)定3]可以像實(shí)例1]一樣,把你要設(shè)置的ulimit放在/etc/profile這個(gè)環(huán)境文件中.
如果針對(duì)所有用戶(hù)設(shè)置,可在/etc/security/limits.conf 設(shè)置.
copyright by ixdba.
簡(jiǎn)述以上五點(diǎn),你可以循序漸進(jìn)依步調(diào)優(yōu),也可以著重調(diào)優(yōu),但有一點(diǎn)你卻要牢記,那就是軟件工程的概論,有一才有二,有因才有果,到頭來(lái)千萬(wàn)不要揀了芝麻丟了西瓜。
轉(zhuǎn)載于:https://www.cnblogs.com/fenghh/p/10442832.html
總結(jié)
- 上一篇: MFC- OnIdle空闲处理
- 下一篇: Unable to instantiat