您的位置:軟件測(cè)試 > 開(kāi)源軟件測(cè)試 > 開(kāi)源單元測(cè)試工具 >
客戶(hù)機(jī)應(yīng)用程序的性能測(cè)試
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時(shí)間:[ 2013/2/21 14:52:40 ] 推薦標(biāo)簽:

SWT 和 JFace 提供了幾個(gè)不同的類(lèi),幫助您在幾個(gè)緩存中管理 GDI 資源。 緩存往往比您想的更靈巧。如何以及何時(shí)使用緩存并不總是顯而易見(jiàn)的。 設(shè)計(jì)時(shí)應(yīng)該注意的幾個(gè)問(wèn)題是:

    GDI 泄漏總是不可接受的,必須進(jìn)行處理。
    處理完泄漏后,您應(yīng)該考慮下面兩個(gè)問(wèn)題:
        應(yīng)用程序需要的總共的 GDI 資源數(shù)目。
        創(chuàng)建這些資源導(dǎo)致的開(kāi)銷(xiāo)。

總共的 GDI 資源數(shù)目

您需要清醒地了解應(yīng)用程序所需要的總共的 GDI 資源數(shù)目, 以及有多少資源是副本。 副本相當(dāng)重要,因?yàn)槟灰锌赡軕?yīng)該共享 GDI 資源以便降低應(yīng)用程序使用的資源數(shù)目。 很容易創(chuàng)建副本,而且您可以都沒(méi)有意識(shí)到(我曾修改了 Sleak 工具使之發(fā)現(xiàn)副本, 并將此改變以及其他有用的改變添加到 Eclipse 中。)

創(chuàng)建 GDI 資源所需的開(kāi)銷(xiāo)

一般而言,創(chuàng)建字體和圖像耗費(fèi)的資源比創(chuàng)建顏色多。 根據(jù)應(yīng)用程序的不同,圖像的創(chuàng)建可能成為某些用戶(hù)動(dòng)作的重大開(kāi)銷(xiāo)。 如果遇到這種情況,您可以考慮使用一些 SWT/JFace 所提供的緩存。

如果可能,應(yīng)讓平臺(tái)來(lái)管理資源。當(dāng)您 在平臺(tái)擴(kuò)展中指定圖像或圖標(biāo)屬性時(shí) —— 比如視圖、動(dòng)作等 —— 平臺(tái)負(fù)責(zé)保證資源被正確地創(chuàng)建和刪除。 好的代碼往往是您無(wú)需編寫(xiě)并維護(hù)的代碼。 上述提示的合理推論是可能時(shí)使用當(dāng)前平臺(tái)的字體和圖像以提高共享。

只要有可能,應(yīng)共享資源。為此,行之有效的方法是把資源集中到 一個(gè)公共包中。您可以將此視為重構(gòu)公共資源。

每個(gè) UI 包都有一個(gè)與之相關(guān)的 ImageRegistry。 該注冊(cè)項(xiàng)可用于存儲(chǔ)常用圖像。這里的關(guān)鍵是常用。我曾見(jiàn)到過(guò)開(kāi)發(fā)人員把所有的資源都 放到了這個(gè)注冊(cè)項(xiàng)內(nèi),這并不合適。該注冊(cè)項(xiàng)維護(hù)著一個(gè)由名稱(chēng) > 圖像或名稱(chēng) > 圖像描述符構(gòu)成的映射。 圖像描述符是對(duì)圖像的輕量描述;它們并沒(méi)有與之相關(guān)的任何 GDI。 您可以用圖像描述符提前得到圖像注冊(cè)項(xiàng),那么當(dāng) 首次需要用到該圖像時(shí),注冊(cè)項(xiàng)會(huì)為您創(chuàng)建它。

對(duì)于較為不常用的圖像,您可以自行創(chuàng)建或刪除之,此外您還可以使用 LocalResourceManager。其構(gòu)造函數(shù)的一種形式采用了小部件。 以此方式創(chuàng)建時(shí),LocalResourceManager 會(huì)在銷(xiāo)毀小部件時(shí)清空 與之相關(guān)的資源。

偵聽(tīng)器泄漏(Listener leaking)

偵聽(tīng)器相關(guān)的泄漏是 UI 代碼常常出現(xiàn)的問(wèn)題(請(qǐng)參閱 參考資料)。 偵聽(tīng)器泄漏往往會(huì)浪費(fèi)內(nèi)存和時(shí)間。當(dāng)您向一個(gè)對(duì)象添加偵聽(tīng)器時(shí), 您是在小部件和偵聽(tīng)器之間創(chuàng)建了一個(gè)直接的、牢固的關(guān)聯(lián)(參看圖 2)。只要小部件存在, 偵聽(tīng)器及其引用的一切都會(huì)一直駐留在內(nèi)存中。 當(dāng)小部件或它的父容器被關(guān)閉, SWT 刪除偵聽(tīng)器,從而打破那個(gè)牢固的關(guān)聯(lián)。 我曾見(jiàn)過(guò)的很多代碼都說(shuō)明了開(kāi)發(fā)人員往往在這個(gè)問(wèn)題上不甚清楚。

只要從中添加偵聽(tīng)器的對(duì)象會(huì)及時(shí)刪除,您無(wú)需刪除 JFace/SWT 偵聽(tīng)器。 關(guān)鍵是理解從中添加偵聽(tīng)器的對(duì)象的生命周期。 不管什么時(shí)候要向某個(gè)對(duì)象中添加偵聽(tīng)器,您都需要自問(wèn)一下, 偵聽(tīng)器被添加到哪個(gè)對(duì)象,偵聽(tīng)器的生命期有多長(zhǎng)。

舉例而言,假設(shè)應(yīng)用程序創(chuàng)建了一個(gè)視圖。該視圖包含一個(gè)按鈕。 在您構(gòu)建該視圖時(shí),您為按鈕添加了一個(gè)選擇偵聽(tīng)器,以便應(yīng)用程序能夠?qū)Π粹o單擊作出響應(yīng)。 您無(wú)需為刪除按鈕的偵聽(tīng)器而對(duì)視圖添加一個(gè)刪除偵聽(tīng)器, 您也無(wú)需為按鈕被撤銷(xiāo)時(shí)刪除按鈕的偵聽(tīng)器而對(duì)按鈕再添加一個(gè)刪除偵聽(tīng)器。 SWT 會(huì)在按鈕被撤銷(xiāo)時(shí)執(zhí)行對(duì)按鈕偵聽(tīng)器的刪除。您不必寫(xiě)這些冗余的代碼和管理多余的工作。

在 RCP 應(yīng)用程序中,經(jīng)常會(huì)有某人創(chuàng)建一個(gè)視圖并將其自身添加為 workbench 頁(yè)偵聽(tīng)器。 Workbench 頁(yè) 往往很長(zhǎng)壽,直到該應(yīng)用程序關(guān)閉,workbench 頁(yè)才會(huì)被關(guān)閉(從而清空偵聽(tīng)器)。 在此情況下,您不應(yīng)該依賴(lài) workbench 頁(yè)清空偵聽(tīng)器關(guān)聯(lián)。您應(yīng)當(dāng)在視圖被關(guān)閉時(shí)把該視圖作為偵聽(tīng)器刪除。

我曾在一個(gè)聊天程序中看到過(guò)另一個(gè)受惑于對(duì)象生命周期的例子。 每當(dāng)打開(kāi)一個(gè)聊天窗口,都會(huì)向伙伴列表添加一個(gè)偵聽(tīng)器。 聊天窗口永遠(yuǎn)不刪除偵聽(tīng)器,只要伙伴列表沒(méi)有被撤銷(xiāo),不會(huì)有什么問(wèn)題。 終結(jié)果是越來(lái)越多的偵聽(tīng)器被添加到伙伴列表,而且它們永遠(yuǎn)不會(huì)被刪除。 需要強(qiáng)調(diào)的是這不僅是內(nèi)存泄漏,也是對(duì)性能的破壞。 偵聽(tīng)器泄漏的后果是,每個(gè)聊天窗口以及它所有可訪問(wèn)的對(duì)象都駐留在內(nèi)存。 同時(shí),每次當(dāng)伙伴列表向列表內(nèi)的偵聽(tīng)器發(fā)信號(hào),都會(huì)浪費(fèi)時(shí)間去通知那些本來(lái)已經(jīng)被關(guān)閉的聊天窗口。

還有一種常見(jiàn)的情形,是把偵聽(tīng)器添加到偏好存儲(chǔ)以便您能夠在偏好改變時(shí)更新 UI。 我曾見(jiàn)過(guò)有開(kāi)發(fā)人員在創(chuàng)建視圖或創(chuàng)建動(dòng)作時(shí)添加偏好存儲(chǔ)偵聽(tīng)器。 問(wèn)題在于如果您不刪除偏好存儲(chǔ)偵聽(tīng)器,您會(huì)導(dǎo)致偵聽(tīng)器累積,因?yàn)?一般而言,偏好存儲(chǔ)只有在應(yīng)用程序關(guān)閉時(shí)才會(huì)被關(guān)閉。

動(dòng)作是一個(gè)特殊的例子。動(dòng)作并不真的有生命周期。 它們被創(chuàng)建后,即使被撤銷(xiāo)或不再使用,您也并沒(méi)有對(duì)它有什么控制能力。 這意味著當(dāng)您創(chuàng)建一個(gè)動(dòng)作時(shí),您一般不應(yīng)該向其他對(duì)象添加偵聽(tīng)器, 因?yàn)槟](méi)有好的方法以刪除那些偵聽(tīng)器。

如何發(fā)現(xiàn)偵聽(tīng)器泄漏
為發(fā)現(xiàn)偵聽(tīng)器泄漏,我推薦兩個(gè)方法:

    審查代碼:我會(huì)搜尋應(yīng)用程序代碼中向?qū)ο筇砑觽陕?tīng)器的位置,在那些位置上我認(rèn)為 偵聽(tīng)器的生存時(shí)間超過(guò)我的預(yù)期。對(duì)這些偵聽(tīng)器列表后,我一般在運(yùn)行時(shí)使用調(diào)試器 驗(yàn)證我的假設(shè)。即使每個(gè) addListener 都對(duì)應(yīng)有 removeListener 也并不代表沒(méi)有問(wèn)題, 因?yàn)殚_(kāi)發(fā)人員往往會(huì)犯一個(gè)錯(cuò)誤,是把 removeListener 包含到某個(gè)方法中, 他們以為該方法會(huì)被調(diào)用而實(shí)際上卻沒(méi)有。

    使用剖析器或差異分析,按如下步驟:
        啟動(dòng)應(yīng)用程序。
        預(yù)熱。
        得到一個(gè)內(nèi)存快照。
        做 5 次動(dòng)作(打開(kāi)聊天窗口、讀取郵件消息等)。
        得到一個(gè)內(nèi)存快照。
        分析應(yīng)用程序?qū)ο蟮膶?shí)例數(shù)目。 如果有偵聽(tīng)器泄漏的話,比如說(shuō),您可能會(huì)發(fā)現(xiàn)有多出的 5 個(gè)本不應(yīng)存在的偵聽(tīng)器。


結(jié)束語(yǔ)

我希望本文能為您提供一些關(guān)于如何在不同構(gòu)建之間度量應(yīng)用程序中堆使用的想法, 還有幾個(gè)手工技術(shù)用于發(fā)現(xiàn)并處理不可避免的泄漏。 如果您還沒(méi)有做好準(zhǔn)備,試著跟蹤應(yīng)用程序在構(gòu)建時(shí)耗費(fèi)的資源量。 做了這些之后,您可以嘗試進(jìn)行堆分析。 即便您一開(kāi)始對(duì)于堆轉(zhuǎn)儲(chǔ)還做不了什么,在構(gòu)建時(shí)收集這些轉(zhuǎn)儲(chǔ)對(duì)于日后使用具有極大價(jià)值。 開(kāi)始收集堆轉(zhuǎn)儲(chǔ)之后,您能夠?qū)τ驅(qū)ο笞霾町惙治。從小做起,?dāng)您熟悉這些技術(shù)后可以加入更多的分析。

上一頁(yè)12345下一頁(yè)
軟件測(cè)試工具 | 聯(lián)系我們 | 投訴建議 | 誠(chéng)聘英才 | 申請(qǐng)使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd