程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 用Runtime Spy調整Eclipse的啟動性能,第1部分 - 開始

用Runtime Spy調整Eclipse的啟動性能,第1部分 - 開始

編輯:關於JAVA

我們幾乎每天都會聽說有新的公司選用 Eclipse 作為他們的應用程序開發平 台。盡管所有這些公司的產品(更不用說所有的 Eclipse 組織成員公司的產品 了)的安裝設置可能是正在趨於相同,但是內存使用過多和性能下降的風險還是 很大。本文介紹了一個非常有用卻鮮為人知的工具,Runtime Spy,來幫助插件開發者。Runtime Spy 透視圖是核心團隊(Core team)的偵探和工具(Spies and Tools)小組的一部分。

注意:核心工具只能運行於 Eclipse 版本 2.x。在本文發表時,它們還不能 運行於 Eclipse 3.0 驅動程序上;編號為 47518 的 bug 描述了這一問題。

為什麼 Eclipse 需要快速啟動

Eclipse 的體系結構是為了在運行期發現其環境的擴展而設計的。這種體系 結構化擴展能力讓很多工具可以無縫地集成到 Eclipse 中。Eclipse 架構師在 項目早期就意識到,這些擴展不能在客戶機代碼中以程序控制的方式定義,因為 當 Eclipse 集成了越來越多的擴展後,累積的啟動開銷將變得無法接受。從而 ,這些擴展由 插件 定義。

為了在保持靈活性的同時避免啟動開銷,插件靜態地將它的擴展定義在一個 清單文件(manifest file)中。插件清單定義了足夠的信息,使 Eclipse 平台 可以延遲加載代碼,同時仍可以識別擴展的初始影響。例如,用戶界面擴展點需 要足夠的信息來描繪初始的用戶界面元素(例如,所提供的工具條按鈕的圖標和 熱區提示(tooltip)文本),這樣平台可以推遲插件代碼的加載,直到用戶真 正選擇一個菜單選項、選擇一個工具條按鈕、打開一個屬性頁或者啟動某個向導 時才加載。插件的最初開銷只是對其清單的解析。XML 格式的解析很快,結果保 存到磁盤,下次還可再用,這樣,當定義了新的插件或者擴展時,啟動不會受到 顯著影響。不過,有一些方法會無意中讓這種好處失效,從而增加了啟動時間和 內存消耗。

幸運的是,Eclipse 插件開發者可以使用 Runtime Spy 透視圖來幫助追蹤這 些問題。本文介紹了核心工具插件和它的 Runtime Spy,並介紹了 readme 文件 內容之外的對其實用工具的一些零散描述。

安裝核心工具

安裝很簡單。只需要下載核心工具壓縮包並解壓縮到您的 <inst_dir>\eclipse\plugins 目錄。接下來決定您是不是希望偵探您的 底層 Eclipse 設施(使用 -debug 命令行選項),或者是不是希望偵探您的運 行期工作台(使用它的啟動配置的 Tracing 頁。我們將在“ 偵探運行期工作台 ”回到這一話題)。現在讓我們來看第一個選擇:偵探您的底層 Eclipse 設施 。

首先,從 plugins\org.eclipse.core.tools_1.0.2 子目錄下拷貝 .options 文件到您的 <inst_dir>\eclipse 目錄來,以啟用所有可用的 Spy 選項 。這將啟用除了類監視以外的所有選項。要監視類的加載,您必須在 plugins\org.eclipse.core.boot_1.0.2\trace.properties 文件中列出包含您 所感興趣的類的包或者插件。在“ 查看插件的哪些類被加載”部分我們再向您 介紹如何指定這些內容。

然後啟動 Eclipse,不要忘記指定 -debug 命令行選項,這會去讀位於 <inst_dir>\eclipse 目錄下 .options 文件。另一種方法,您可以將 .option 文件所在的位置標識為 -debug 選項的一個參數(例如, -debug file:d:\...\.options )。

偵探工作台

我們假定您已經安裝了核心工具文件,並重新啟動了 Eclipse。由於已經指 定了 -debug 命令行參數,您將會看到定向到標准輸出的一些啟動消息。當處於 調試模式時,這些將顯示在一個單獨的命令提示窗口中,如圖 1 所示。

圖 1. 對 -debug 選項的指定打開了一個顯示標准輸出消息的命令提示窗口

既然每個 Runtime Spy 的視圖都已經啟動並運行,讓我們來快速浏覽一下這 些視圖。不要忘記,Spy 作為“spied”插件在同一個工作台中運行,因此在使 用工具本身的正常過程中可能會有一些插件被激活。這通常沒關系,因為它只是 用到了底層的功能,而這些功能應該已經加載或者早晚都得加載。有一種情況未 必會出現,但確實重要,那就是別忘了它的視圖只是根據需要而更新,所以 Runtime Spy 透視圖第一次打開時,它將只顯示出在它自己啟動之 前 就已經在 運行的那些插件。

查看哪些插件在運行

選擇 Window > Open Perspective > Runtime Spy打開四個視圖,如 圖 2 所示。

圖 2. Runtime Spy 透視圖由 Activated Plugins、Loaded Classes、 Plugin Datasheet 和 Stack Trace 視圖組成

如果您忘記了指定 -debug 選項,您將看到 Activated Plugins視圖中顯示 出“Plugin monitoring is not enabled”消息。由於默認沒有類在被監視,因 此 Loaded Classes視圖將包含“Class monitoring is not enabled”消息。捕 獲類加載信息會使 Eclipse 變慢,因此您必須通過指定包含您所感興趣的類的 包或插件來列出那些類。現在我們只是關心哪些插件被加載了。圖 3 顯示了 Runtime Spy 的主要視圖, Activated Plugins。

圖 3. Runtime Spy 中顯示的 Activated Plugins 視圖

如果您希望在 Runtime Spy 視圖中顯示內存使用率統計( Alloc、 Used和 Rom Used列),您必須用支持 J9 技術的 IBM Java 運行期環境(Runtime Environment)。這個 JRE 包含在名為 WebSphere Studio Workbench 的 IBM 版本 Eclipse 中,您在 IBM PartnerWorld for Developers 注冊後就可以免費 下載得到它。記住將 J9 指定為 Java 運行期環境的一個參數(例如, eclipse -debug -vmargs -Xj9 )。

點擊第一列的標題, Plugin,將排序改為升序、降序和分組升序。在“+” 號之下分組的插件是父插件運行的時候需要運行的那些插件。當加載的插件被分 組的時候,行的值對應於插件以及它所有子插件。當您想要將重量級(資源)消 耗者以一個組來查看時,可以使用這種排序。

後面跟有一個星號的插件名是那些在啟動的時候就加載的插件。不管名字意 味著什麼,Activated Plugins 視圖中標記了星號的啟動插件集合裡,並不包括 工作台處理其 org.eclipse.ui.startup 擴展點時加載的那些插件。更確切地說 ,工作台是在初始啟動以後才處理這些擴展的部分。

特別有趣的是 Order 列。點擊這一列的標題,將插件列表以加載順序排序。 如果您希望快速查看給定的動作激活了哪個插件,先選中所有的插件(Ctrl+A) ,執行那個動作,再回到 Activated Plugins 視圖,然後選擇 按鈕。沒有被選中的就是那些剛被激活的插件。另外一種方法是,記 錄下在您的動作之前已經在運行的最後一個插件的序號值,然後更新,來查看那 些排序更高的插件。

查看插件的哪些類被加載

插件的類是按需要加載的。通過延遲這些引用或者減少對一些類的引用,您 有可能會節約內存和啟動時間。Loaded Classes 視圖將幫您查看所選擇的插件 到現在為止哪些類已經被加載了。要更新 Loaded Classes 視圖,在 Activated Plugin 列表中選擇一個或多個插件,然後選擇 按鈕。圖 4 中顯示的是 org.eclipse.jdt.core 插件已加載的類, 以加載順序排序。

圖 4. Runtime Spy 中顯示的 Loaded Classes 視圖

除了插件激活次序外,我發現,通過對引用次序進行排序,這個視圖還可以 用來得到一個給定動作所初始化的類和序列的“整體圖(big picture)”。這 個列表中包括了插件啟動代碼,讓您充分認識到執行它的代價。這個故事的寓意 通常是“啟動時做的太多了”。

追蹤一個類為什麼被加載

要更清楚地了解是什麼導致了一個插件的激活或者一個類的加載,首先您必 須為引起您關注的類所在的插件或者包啟用追蹤選項。在這個例子中,我創建了 一個 traces.properties 文件,其中一行為 packages=org.eclipse.jface.text 。然後您需要:

在 Activated Plugins 列表中選擇 org.eclipse.jface.text 插件。

按下 按鈕以更新 Loaded Classes 列表。

選擇 org.eclipse.jface.text.ITextViewer 類。

選擇 按鈕來更新 Stack Trace 視圖。

這將顯示出哪些代碼讓類加載器加載了那個類(如果在這之前它還沒有被加 載)並激活了選中的插件,如圖 5 所示。

圖 5. Runtime Spy 中顯示的 Stack Trace 視圖

棧頂通常不值得關注,因為那追蹤的是類加載器代碼本身。有用的信息在中 下部。在這個例子中,棧記錄顯示,是由於 Runtime Spy 透視圖的打開而最終 導致了 ITextViewer 類的加載,如高亮的棧記錄行底部所示。透視圖打開的初 始化視圖中包括 Plugin Datasheet 視圖,這個視圖將用 JFace Text 類 TextViewer 來顯示它的數據。在 defineClass 期間核實那個類時,JVM 發現還 需要 ITextViewer ,因為 TextViewer 實現的是這一接口。如您可以看到的, JVM 運行期的類加載可以嵌套得相當深;出於性能目的您通常應該關注那些引起 類加載器調用的代碼,像圖 5 中顯示的棧記錄的高亮部分。

追蹤插件為什麼被加載

上一個例子說明了一個特定類為什麼會被加載。您還可以查看一個給定的插 件為什麼被加載,但是插件的激活原因看起來不是那麼明顯,因為起因是間接的 。一般情況下,類是由於被另一個類的方法引用而被加載(並且您還可以參考相 應的 import 語句),與之不同,插件的加載是一些間接引用的結果。不要忘記 ,我們的目的是,不到插件被用到的時候盡量不去加載它,所以對插件本身的引 用這樣實現:

顯示地聲明標識,比如插件清單中的 <import plugin="org.eclipse.ui"> ,或者

隱式地標識,比如為那個插件導出包到運行期 JAR 中。

這兩個例子都在“Hello, Eclipse”插件清單節選中突出顯示了,見清單 1 。

清單 1. “Hello, Eclipse”的擴展點樣例

<?xml version="1.0" encoding="UTF-8"?>
<plugin ...>

      ... lines omitted ...

   <runtime>

      <library name="hello.jar"/>
      <export name="*"/>
    </library>
   </runtime>
   <requires>
    <import plugin="org.eclipse.core.resources"/>

      <import plugin="org.eclipse.ui"/>
   </requires>

      ... lines omitted ...
   <extension point="org.eclipse.ui.actionSets">
    <actionSet
      label="Sample Action Set"
      visible="true"
      id="hello.actionSet">
      <menu
       label="Sample &Menu"
       id="sampleMenu">
       <separator
         name="sampleGroup">
       </separator>
      </menu>
      <action
       label="&Sample Action"
       icon="icons/sample.gif"

      class="hello.actions.SampleAction"
       tooltip="Hello, Eclipse world"
       menubarPath="sampleMenu/sampleGroup"
       toolbarPath="sampleGroup"  id="hello.actions.SampleAction">
      </action>
    </actionSet>
   </extension>

對 org.eclipse.ui.actionSets 擴展點動作設置的貢獻隱式地依賴於定義插 件,即 Workbench UI 插件(org.eclipse.ui)。Workbench 插件會去讀取插件 注冊表,那裡包含了對它的 org.eclipse.ui.actionSets 擴展的這一貢獻,並 創建相應的動作設置。SampleAction 類將不會在這裡被加載,因此包含它的插 件也不會被加載。取而代之的是,Workbench 插件定義了一個委派動作來代表用 戶界面中的選擇,這個委派動作會等待,直到用戶真正選擇它才創建 SampleAction 的一個實例來處理響應。

為創建 SampleAction 的一個實例,動作代表(action delegate)調用插件 注冊表實例 IConfigurationElement 的 createExecutableExtension 方法,對 應於我們的例子清單文件中指定的 <action class="hello.actions.SampleAction" ...> 標簽。雖然那樣不錯,但是有 時在棧記錄結果中不容易看出來。讓我們來仔細看一個比“Hello, Eclipse”按 鈕選擇更難的例子。圖 6 顯示了一個由可執行擴展處理而導致的典型(插件) 激活。現在讓我們用 Stack Trace 視圖來確定其原因,步驟同前。

圖 6. Stack Trace 視圖顯示了可執行擴展的啟動

在這個例子中,我們從棧記錄高亮部分的底部可以看出,這些都是源於 PDE 的 Plug-ins 視圖中的一次雙擊。默認的動作處理者負責處理請求 Workbench 打開 Plug-in Manifest 編輯器的動作,隨後激活 org.eclipse.ui.editors 插 件。棧記錄的高亮部分只是顯示了擴展點處理器的代碼,因為它對 Workbench 插件類 (org.eclipse.ui) 的引用是間接的。通過六次類似的棧記錄,您將識別 出對 IConfigurationElement.createExecutableExtension 調用前後重要的部 分,並很快看出是誰啟動了它以及結果是什麼。您可以再次選擇 按鈕來更新加載的類並重新按加載順序排序,以更好地了解插件啟動 後發生了什麼事情。

其他有用的視圖

最後, Plugin Datasheet視圖總結了一些有趣的統計數據,例如插件定義了 多少資源和擴展,如圖 7 所示。

圖 7. Plugin Datasheet 顯示被使用的資源

這個視圖追蹤了由 IPluginDescriptor.getResourceString 方法及其變量加 載的資源束(resource bundle)數據。這一總結信息得益於這樣一個事實,即 Eclipse 平台運行期有其自己的類加載器,並且類加載器像處理類一樣處理資源 束,因此保持對資源數據統計的追蹤很簡單。“not loaded yet”消息表示實際 上插件注冊表寫到了磁盤上,它所引用的部分只是在需要的時候才加載。

偵探運行期工作台

前一節介紹了偵探 Eclipse 本身的底層設施。更實際的是,您會希望偵探測 試版工作台,稱為 運行期工作台。您可以選擇 Run > Run As... > Run -time Workbench並轉到 Tracing 頁,來配置您希望啟動的運行期工作台的實例 ,如圖 8 所示。

圖 8. 在 Tracing 頁中設置 Runtime Spy 選項

org.eclipse.core.boot 插件的調試選項也位於我們前面討論的 <inst_dir>\eclipse\plugins\org.eclipse.core.boot_2.1.1\.options 文件選擇中。這個文件定義了您幾乎肯定會期望的默認值 (每個都打開)。不 過,如果您想對所用的時間進行比較精確的性能測量,那麼您應該將啟用的選項 減少到最少,尤其是需要使用棧記錄的那些(即 trace/pluginactivation 等) 。將 monitor/plugins 設置為 true,其他都設置為 false,這樣帶來的性能開 銷很少。

其他信息

您可以找到很多關於 Java 性能調整的資料,但是很少是專門針對 Eclipse 的。本文向您介紹的工具是用來理解和診斷插件運行相關的啟動性能問題最好的 工具之一。結束之前,有必要關注核心工具向您提供的一些其他有用的診斷信息 :

Plug-in Dependency透視圖顯示的信息與 Plug-in Registry視圖中顯示的信 息類似(通過 Window > Show View > Other... > PDE Runtime > Plug-in Registry調用),但是帶有一個關於選中插件所依賴插件的詳盡列表。

考慮過工作空間(Workspace)的 .metadata 目錄中有什麼內容嗎? Metadata透視圖將幫您在它的結構中漫游。不過前提是得對工作空間實現有相當 深入的理解。

一類 Resource Tools視圖描述的是對資源改變監聽程序和 resource delta 、builder 等等的洞察。那些學習工作空間 API 的人尤其應該注意 Resource、 Delta和 Builder/Listener視圖。選擇 Window > Show View > Other... > Resource Tools來訪問這些視圖。

您可以在核心工具的 readme 中進一步了解這些工具。

本系列文章的第 2 部分將向您介紹我是如何使用 Runtime Spy 來診斷 WebSphere Studio Application Developer 版本 5.1.1 的幾個啟動問題的。其 後,取決於運行的視圖和透視圖,啟動性能提高了 11% 到 37%,這就證明,對 您的插件何時被激活及被激活的原因的理解,可以幫助實現 Eclipse 的快速啟 動。

等待 WebSphere Studio 版本 6.0 吧,我們將 真正提高啟動性能!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved