隨筆-8  評(píng)論-19  文章-2  trackbacks-0

          基本知識(shí)

          1.1 性能是什么

          在性能調(diào)優(yōu)之前,我們首先來(lái)了解一下性能是什么?關(guān)于性能,我想每個(gè)學(xué)習(xí)過(guò) Java 的人都能列出幾點(diǎn),甚至可以夸夸其談。在《 Java TM Platform Performance 》一書(shū)中,定義了如下五個(gè)方面來(lái)作為評(píng)判性能的標(biāo)準(zhǔn):

          1) ????? 運(yùn)算的性能——哪一個(gè)算法的執(zhí)行性能最好?

          2) ????? 內(nèi)存的分配——程序運(yùn)行時(shí)需要耗費(fèi)多少內(nèi)存?

          3) ????? 啟動(dòng)的時(shí)間——程序啟動(dòng)需要多長(zhǎng)時(shí)間?這在 Web 項(xiàng)目中的影響不大,但要注意部分程序需要部署或運(yùn)行在客戶(hù)端時(shí)的情形(比如 applet 程序)。

          4) ????? 程序的可伸縮性——在壓力負(fù)載的情況下,程序的性能如何?

          5) ????? 性能的感知——用戶(hù)在什么情況下會(huì)覺(jué)得程序的性能不好?

          以上五個(gè)方面,在具體的使用場(chǎng)景可以有選擇的去評(píng)判。至于這五方面的性能調(diào)優(yōu),在后續(xù)的章節(jié)中將會(huì)陸續(xù)的給以相應(yīng)的性能調(diào)優(yōu)策略。

          1.2 調(diào)優(yōu)的規(guī)則

          我們只需要關(guān)心對(duì)我們程序有影響,可以察覺(jué)到的性能問(wèn)題,而不是每一個(gè)類(lèi)中的每一個(gè)方法我們都需要想方設(shè)法的提高性能。如果程序的性能沒(méi)有達(dá)到我們所期望的要求,我們才需要考慮如何優(yōu)化性能。同樣的,晦澀的代碼雖然提高了程序的性能,但同時(shí)可能帶給我們的是維護(hù)的噩夢(mèng)。我們需要折中的考慮以上兩種情況,使得程序的代碼是優(yōu)美的,并且運(yùn)行的足夠快,達(dá)到客戶(hù)所期望的性能要求。

          優(yōu)化代碼甚至?xí)?dǎo)致不良的結(jié)果, Donald Knuth (一位比較牛比較有影響的人物,具體是誰(shuí),我也忘了,誰(shuí)知道,可以告訴我一下,謝謝?。┰f(shuō)過(guò),“ Premature optimization is the root of all evil” 。在開(kāi)始性能調(diào)優(yōu)前,需要先指出不優(yōu)化代碼的一些理由。

          1) ????? 如果優(yōu)化的代碼已經(jīng)正常工作,優(yōu)化后可能會(huì)引入新的 bug ;

          2) ????? 優(yōu)化代碼趨向于使代碼更難理解和維護(hù);

          3) ????? 在一個(gè)平臺(tái)上優(yōu)化的代碼,在另一個(gè)平臺(tái)上可能更糟;

          4) ????? 花費(fèi)很多時(shí)間在代碼的優(yōu)化上,提高了很少的性能,卻導(dǎo)致了晦澀的代碼。

          確實(shí),在優(yōu)化前,我們必須認(rèn)真的考慮是否值得去優(yōu)化。

          1.3 調(diào)優(yōu)的步驟

          一般我們提高應(yīng)用程序的性能劃分為以下幾個(gè)步驟:

          1) ????? 明確應(yīng)用程序的性能指標(biāo),怎樣才符合期望的性能需求;

          2) ????? 在目標(biāo)平臺(tái)進(jìn)行測(cè)試;

          3) ????? 如果性能已經(jīng)達(dá)到性能指標(biāo), Stop

          4) ????? 查找性能瓶頸;

          5) ????? 修改性能瓶頸;

          6) ????? 返回到第 2 步。

          JDK 調(diào)優(yōu)

          2.1 選擇合適的 JDK 版本

          不同版本的 JDK ,甚至不同廠家的 JDK 可能都存在著很大的差異,對(duì)于性能優(yōu)化的程度不同。一般來(lái)說(shuō),盡可能選擇最新發(fā)布的穩(wěn)定的 JDK 版本。最新的穩(wěn)定的 JDK 版本相對(duì)以前的 JDK 版本都會(huì)做一些 bug 的修改和性能的優(yōu)化工作。

          2.2 垃圾收集 Java 堆的優(yōu)化

          垃圾收集就是自動(dòng)釋放不再被程序所使用的對(duì)象的過(guò)程。當(dāng)一個(gè)對(duì)象不再被程序所引用時(shí),它所引用的堆空間可以被回收,以便被后續(xù)的新對(duì)象所使用。垃圾收集器必須能夠斷定哪些對(duì)象是不再被引用的,并且能夠把它們所占據(jù)的堆空間釋放出來(lái)。如果對(duì)象不再被使用,但還有被程序所引用,這時(shí)是不能被垃圾收集器所回收的,此時(shí)就是所謂的“內(nèi)存泄漏”。監(jiān)控應(yīng)用程序是否發(fā)生了內(nèi)存泄漏,有一個(gè)非常優(yōu)秀的監(jiān)控工具推薦給大家—— Quest 公司的 JProbe 工具,使用它來(lái)觀察程序運(yùn)行期的內(nèi)存變化,并可產(chǎn)生內(nèi)存快照,從而分析并定位內(nèi)存泄漏的確切位置,可以精確定位到源碼內(nèi)。這個(gè)工具的使用我在后續(xù)的章節(jié)中還會(huì)做具體介紹。

          Java 堆是指在程序運(yùn)行時(shí)分配給對(duì)象生存的空間。通過(guò) -mx/-Xmx -ms/-Xms 來(lái)設(shè)置起始堆的大小和最大堆的大小。根據(jù)自己 JDK 的版本和廠家決定使用 -mx -ms -Xmx -Xms Java 堆大小決定了垃圾回收的頻度和速度, Java 堆越大,垃圾回收的頻度越低,速度越慢。同理, Java 堆越小,垃圾回收的頻度越高,速度越快。要想設(shè)置比較理想的參數(shù),還是需要了解一些基礎(chǔ)知識(shí)的。

          Java 堆的最大值不能太大,這樣會(huì)造成系統(tǒng)內(nèi)存被頻繁的交換和分頁(yè)。所以最大內(nèi)存必須低于物理內(nèi)存減去其他應(yīng)用程序和進(jìn)程需要的內(nèi)存。而且堆設(shè)置的太大,造成垃圾回收的時(shí)間過(guò)長(zhǎng),這樣將得不償失,極大的影響程序的性能。以下是一些經(jīng)常使用的參數(shù)設(shè)置:

          1) ????? 設(shè)置 -Xms 等于 -XmX 的值;

          2) ????? 估計(jì)內(nèi)存中存活對(duì)象所占的空間的大小,設(shè)置 -Xms 等于此值, -Xmx 四倍于此值;

          3) ????? 設(shè)置 -Xms 等于 -Xmx 1/2 大小;

          4) ????? 設(shè)置 -Xms 介于 -Xmx 1/10 1/4 之間;

          5) ????? 使用默認(rèn)的設(shè)置。

          大家需要根據(jù)自己的運(yùn)行程序的具體使用場(chǎng)景,來(lái)確定最適合自己的參數(shù)設(shè)置。

          除了 -Xms -Xmx 兩個(gè)最重要的參數(shù)外,還有很多可能會(huì)用到的參數(shù),這些參數(shù)通常強(qiáng)烈的依賴(lài)于垃圾收集的算法,所以可能因?yàn)?/span> JDK 的版本和廠家而有所不同。但這些參數(shù)一般在 Web 開(kāi)發(fā)中用的比較少,我就不做詳細(xì)介紹了。在實(shí)際的應(yīng)用中注意設(shè)置 -Xms -Xmx 使其盡可能的優(yōu)化應(yīng)用程序就行了。對(duì)于性能要求很高的程序,就需要自己再多研究研究 Java 虛擬機(jī)和垃圾收集算法的機(jī)制了??梢钥纯床軙凿摲g的《深入 Java 虛擬機(jī)》一書(shū)。?


          ?
          posted on 2007-03-19 10:12 jie_java 閱讀(360) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 漾濞| 祁门县| 岳阳县| 金阳县| 商都县| 区。| 甘孜| 本溪市| 介休市| 贺兰县| 左贡县| 浠水县| 鹤峰县| 青阳县| 瓦房店市| 门源| 南溪县| 丹阳市| 蓬溪县| 桦甸市| 乐陵市| 宁强县| 徐汇区| 神木县| 观塘区| 济宁市| 西和县| 建阳市| 宝丰县| 祁阳县| 平顶山市| 青铜峡市| 台安县| 平湖市| 全椒县| 屏东市| 天等县| 华安县| 紫云| 阳新县| 太湖县|