副标题#e#
Runtime Spy 是 Eclipse.org 提供的焦点东西 (Core Tools)之一,它是特 别设计的一个透视图及一组视图,用于辅佐您找到并诊断插件启念头能问题。其 中的一个案例研究说明白Runtime Spy 如何用于提高 IBM WebSphere Studio Application Developer 的启念头能。上一篇文章,也就是 第1 部门,对 Runtime Spy 举办了先容。
阅读完本系列文章的 第 1 部门 后,您应该已经对 Runtime Spy 如何来帮 助您查找启动问题的位置有了概略的认识。让我们通过一些特定的例子来弄大白 如何用它淘汰您的插件启动时间。为了让话题更有可读性,我们将探讨一些在 Runtime Spy 辅佐下更正的问题,这些问题的更正是 IBM WebSphere Studio Application Developer 机能提高的一个方面。
留意:焦点东西只能运行于 Eclipse 版本 2.x。在本文颁发时,它们还不能 运行于 Eclipse 3.0 驱动措施上;编号为 47518 的 bug 描写了这一问题。
辅佐 Eclipse 快速启动
为提高一个基于 Eclipse 的应用措施的启念头能,一般来说有两个方针:
尽大概地延迟插件的激活。
在激活您的插件时将涉及到的事情量减到最少。
这两个方针配合的原则是 尽大概延迟代码的执行。您可以回收的一些要领:
不要加载您的插件
怎么办?首先,要遵循 Eclipse 自己的插件扩展的思 想。不要健忘,许多 Eclipse 扩展点界说要求孝敬者静态地声明足够的信息, 以延迟代码的加载,直到需要执行被请求的行动时才加载。这是 Eclipse 体系 布局的根基思想,在插件清单文件的声明中获得了浮现。您本身的扩展点界说也 应该回收这一要领。
淘汰插件初始化时加载的类的数量
最常呈现问题的处所是 Plugin.startup 要领中的引用。许多插件重载这个要领以完成它们的初始化。抱负的办理要领凡是是,让您的插件延迟它的初始化,直到用户请求您的产物的 某个特定的行动时再初始化。要否则,下一个最好的选择是最小化引用的类和插 件的数量。在任何一种环境下,Runtime Spy 都可以指出那边大概会占用太多的 时间可能触发太多其他插件的激活。
在插件初始化期间淘汰 CPU 操作率
同样,最常呈现问题的处所照旧插件 的 startup 要领的代码可能它所挪用的代码。内存布局的滞后初始化可以节减 CPU 时间并延迟其他插件的激活。尚有一种大概是在启动时派生一个单独的低优 先级的线程,当系统空闲时再去完成初始化,不外这种要领需要出格留意处理惩罚好 同步。
通过延迟插件的激活,会给用户一种产物更为机动的印象。尽量 累积的CPU 时间是完全沟通的,可是相对付在最开始强制完成,将其解析为若干小块在较长 的一段时间内分步完成会进一步低落人们的留意力。在第一次挪用时(也就是启 动您的产物可能打开第一个透视图、编辑器或视图时)尤其不该该有延迟,因为 正是在这个时候用户最存眷于事情的完成而没有太多耐性。
再先容 Runtime Spy
Runtime Spy 为您提供了用于跟踪三种加快启动要领的根基统计表,如图 1 所示。
图 1. Runtime Spy 透视图由 Activated Plugins、Loaded Classes、 Plugin Datasheet、和 Stack Trace 四个视图构成
您的第一个方针是让 Activated Plugins视图中呈现的条目减到最少。对付 那些呈此刻列表中的插件,您的第二个方针应该是让 Loaded Classes视图中出 现的条目减到最少。Activated Plugins 视图中的 Startup time列将为您指出 那些启动时间较长的插件。在 Activated Plugins 中选择 按钮可以更新 Stack Trace视图,让您大白 插件 为何被加载,在 Loaded Classes 视图中选择 按钮将为您说明 类为何被加载。
#p#副标题#e#
侦探 WebSphere Studio
让我们以一个如何利用 Runtime Spy 来诊断和更正启动代码错误的例子来开 始。如您将看到的,这些批改不会在绝对意义上“提高”启念头能,而是延迟了 启动开销,这样会让用户感受产物整体上更快。底层的 Eclipse 产物在这一点 上做得很是好,它会跟着您的利用而将启动开销解析为小块分阶段举办。这是 Eclipse 的延迟插件加载计策的基本。
为对环境举办第一次调查,让我们启动 Studio 时只打开 Runtime Spy 透视 图。这样应该会加载险些最少的插件并以最快的速度启动,如图 2 所示。
图 2. 启动时激活最少数目标插件
提示:快速查察新激活的插件
#p#分页标题#e#
按下 按钮不会改变 Activated Plugin 列表中的已作出的选择。假如您想 查察特定的行动激活了哪些插件:
在列表中选择所有条目 (Ctrl+A)。
执行您期望激活一个或更多插件的行动。
选择 按钮来更新列表。
没有被选中的条目就是新激活的插件;被选中的那些是在行动之前就已经被 激活的。别的一种要领是,您可以记下 Order列中最后加载的插件的编号,执行 行动,然后对 Order 列从头排序,查察哪些插件呈现于先前(已经激活)的最 后一个插件之后。
留意插件名末端的星号。这些插件是在认真启动 Eclipse 的插件被激活时加 载的,谁人插件名为 application plug-in。这个插件提供了一个实现 org.eclipse.core.runtime.applications 扩展点的 IPlatformRunnable 接口 的类。默认地,Workbench UI 插件提供对这个接口的一个实现,来建设事情台 窗口,收集对主菜单栏、东西栏等等的行动孝敬 (action contributions),一 般环境下还要为事务处理惩罚筹备好 Eclipse 事情台用户界面。
实际上耗损的时钟时间将会比 Activated Plugins 视图中显示的 Startup time 列的和要多。这是因为后者不包罗 Platform Runtime 加载之前 JVM 的运 行时间可能插件启动之外的 CPU 运行时间。在图 2 所示的例子中,从启动设置 启动 Run-time Workbench 时起实际上的启动时间约莫是 13 秒。个中还包罗启 动设置自己为构建插件列表等任务而引入的措施调试时间 (development-time) 开销。
纵然加上这些开销,启动时间还长短常少,不是吗?
Workbench 启动扩展点的功效
让我们按下 按钮来更新勾当的插件列表。就是那样!图 3 中是我们的第一个困 惑。
图 3. org.eclipse.ui.startup 扩展点激活的插件
被选中的那些插件是初始化时激活的。那么别的 11 个插件呢?或者有一些 是因 Runtime Spy 透视图而加载的。更为有趣的是,图 3 中有一些看起来可疑 的 Studio 插件。列表顶部显示的是“cheatsheet”和“internet”。它们是什 么?为什么此刻被加载?回到用户界面,我们在 Help下拉菜单下找到了与第一 个插件相关的选项,如图 4 所示。
图 4. org.eclipse.ui.startup 激活的插件可以不被激活吗?
一般只有新用户才会去选择 Cheat Sheets菜单选项,所以我们为什么还要在 启动时为加载它们的相关插件而支付价钱呢? Workbench > Startup首选参 数页提示了谜底,如图 5 所示。
图 5. 为 org.eclipse.ui.startup 扩展点作出孝敬的插件
org.eclipse.ui.startup 扩展点大概是版本 2.0 一直有争议的 API 之一。当事情台窗口打开时它可以全官僚求 Workbench UI 激活插件,而不受延迟加载 计策限制。假如一个插件的清单界说了这一扩展点,那么它的插件类必需实现 IStartup.earlyStartup 要领。
有对这个 API 的正当利用。由于文章长度有限,不能尽述这个列表中每一个 条目。所以让我们来思量如上面图 5 所示添加的两个插件的正当性:
Cheat Sheets. cheat sheel 菜单选项是基于安装的特性而动态构建的,在 每一次选择后会从头排序。没有 Workbench UI 要领来通过扩展实现这一行为。看起来这个插件别无选择,只好继承“cheat”下去。
Internet Preferences. 这一启动代码基于 URL 类的系统属性初始化 Window > Preferences > Internet配置。由于没有步伐可以知道这个类 什么时候会被引用,而且因为没有显式的初始化要领,这样做看起来是正当的。不外,思量利用库扩展大概是明智的。我们稍后将返来表明原因。
首先您大概会迷惑为何 Workbench 会界说一个 Startup 首选参数页。可以 打消选择列出的插件之一,让用户有时机选择用淘汰的成果调换更快速的启动。譬喻,有履历的开拓者不需要 Cheat Sheets 层叠菜单提供的提示,可以选择禁 用它对 org.eclipse.ui.startup 扩展点的孝敬,这样就删除了 Help > Cheat Sheets 菜单选项。假如您本身的插件对这个扩展点有孝敬,那么要记着 这一点。也就是说,要守旧地编写您的插件代码,假定插件类的 IStartup.earlyStartup 要领大概还没有被挪用。
回到我们在图 3 中的例子,思量列表中没有星号的插件 com.ibm.etools.internet 。图 6 中它的栈记录确定了为什么这个插件在事情 台窗口打开后被激活。
图 6. 事情台启动处理惩罚
Workbench 的 run 要领被高亮了,对扩展点的孝敬在这里被处理惩罚。自此今后 激活的插件可能是对 startup 扩展点有孝敬,可能是对个中的引用有孝敬。
找出大概的 WebSphere Studio 热点
#p#分页标题#e#
让我们打开 J2EE 透视图来查察一些 Studio 特定内容。(假如您想诊断一 个简朴些的景象,那么打开一个单一的视图,好比 Window > Show View > DB Servers,而不要打开相应的透视图;那样已激活插件的列表会短许多 。)打开 J2EE 透视图后,回到 Runtime Spy 并选择 Activated Plugin 的 按钮。哇!列表中的插件数从 22 跳到了 73,增加了 20 秒的插件 激活时间(先前总的时间也只有三秒多)。图 7 的显示中以插件的激活顺序对 它们举办排序,最近激活的插件显示于顶部。
图 7. 打开 J2EE 透视图后激活的插件
公正地讲,Runtime Spy 增加了开销,尤其是当需要捕捉栈记录时,所以从 半热态启动 (warm start) 时,实际上不加批改 (uninstrumented) 耗损的总的 时间靠近 37 秒。可是让我们来看一下是否有一些启动插件之外的插件有大概不 必启动。为节减空间,下面这个列表并不完全,因为我们认为根基的组件好比 EMF、JDT 和 J2EE UI 是需要的。可是这些呢?
com.ibm.etools.validation.* (可以被延迟可能设为可选?)
com.ibm.etools.rsc.core.ui (db)
com.ibm.etools.rdblib (db)
com.ibm.etools.sqlmodel.* (db)
com.ibm.sed.preferences (可以被延迟?)
com.ibm.etools.rsc (db)
com.ibm.etools.sqlparse (db)
com.ibm.etools.rdbschemagen.ui (db)
com.ibm.etools.rdbexport.ui (db)
com.ibm.etools.sqlbuilder (db)
com.ibm.etools.subuilder (db 而且需要 1828ms 加载时间!)
com.ibm.etools.sqlj (db)
到此刻并没有与数据库相关的视图可能编辑器被打开。而为什么干系数据库 模式中心 (6) 和那么多其他数据库相关的插件被激活了?插入的“可以被延迟 ”注释暗示 Eclipse 有本领以体系化的办理方案使它们在需要之前不被激活, 这只是关于属性的一种非凡环境。可是,纵然全面地思量,这些大部门都是无足 轻重的。然而,照旧有一些插件耗损了大量的启动时间,并且,如我们所看到的 ,它们的开销与处理惩罚扩展点期间插件激活细密接洽在一起。下一节更全面地表明 了这一开销,并对启动开销是如何发生的举办了研究。然后我们将返回到我们对 J2EE 透视图启动的阐明。
领略插件激活与扩展点处理惩罚之间的干系
通过制止对 subuilder 插件(按它的插件清单的说法,它是 Stored Procedure和 UDF Builder)的激活来节减启动时间看起来可以乐成,因为它需 要用去总时间的 10%。另外,它险些是在激活序列的最后(73 其中的第 72 个 ),所以,举办“修剪 (trim off)”大概要比制止序次靠前的插件激活更为简 单。这个插件激活的栈记录见图 8。
图 8. com.ibm.etools.subuilder 的插件激活栈记录
Studio 的源代码不需要去领略产生了什么;栈记录就足以指出原因。Eclipse 类 PartPane 打点您看到的那些选项卡视图,包罗 J2EE Hierarchy、 Package Explorer和 Navigator 视图。如图 8 所示,在选择的文本下方,选项 卡视图 PartPane 正在实验建设与 J2EE Hierarchy 选项卡相关联的视图的一个 实例,类的名字为 J2EEView 。进一步查察记录的上方,我们看到这个类反过来 挪用了一个辅佐者 (helper),然后这个辅佐者挪用了 createExecutableExtension 要领。
IConfigurationElement.createExecutableExtension 要领值得出格留意。当您调试您本身的机能问题时,您将会发明,这个要教育致了 Rumtime Spy 没 有发明的许多插件的激活案例。为更好地领略它做了些什么以及它如何影响插件 激活,思量清单 1 中给出的简朴的扩展点孝敬。您大概会发明,这与 第 1 部 分中类型的“Heloo Eclipse”样例的清单是沟通的。
清单 1. “Hello, Eclipse”的样例扩展点
#p#分页标题#e#
<?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>
留意对 <action> 标签的 class 属性 的处理惩罚。这指定了未来处理惩罚菜单选项选择的类的名字,这个类必需实现 IWorkbenchWindowActionDelegate 接口。这个类并不位于处理惩罚 org.eclipse.ui.actionSets 扩展点的同一个插件中(Workbench UI 插件), 也不位于它的先决插件中。那么,当它看起来不取决于插件的 classpath 时, Workbench UI 插件如何去建设这个类的一个实例呢?
插件的类加载器 (classloader) 认真在它的库中理会对类的引用。类加载器 将插件引用映射到它们相应的包括有插件类的 JAR 文件,好比我们的例子, SampleAction 。因此,Workbench UI 插件不必“知道”通过属性引用的类,比 如 <action> 标签的 class 。相反,是由于“Hello Eclipse”插件界说 了对 Workbench UI 插件的依赖而使之可以会见方针插件的类,因而有权通过目 标插件的类加载器会见 Hello Eclipse 的类。简捷地重述一遍,当 Eclipse 找 不到某个类时,它会要求方针插件的类加载器去加载谁人类;那就是 createExecutableExtension 要领所做的工作。
制止与扩展点处理惩罚相关的过早的插件激活
回到图 8 中所示的栈记录,我们可以发明,在所选择的文本中部的代码通过 挪用 createExecutableExtension 对扩展孝敬举办处理惩罚 —— 看吧! 插件开始 加载了。我们此刻要寻觅的是明摆着的问题的谜底:这时需要加载它吗?可以将 它的加载向后延迟吗?
实际上所有会激活另一个插件的类最终都可以追溯到对 createExecutableExtension 要领的挪用。这些挪用的挪用参数指明白属性名( 凡是是 “ class ”)和它的值,即要加载的类的全名。这就带我们回到了导致 激活(此插件)的插件扩展孝敬,在我们的例子中也就是 subuilder 插件。清 单 2 是它的清单的摘录。
清单 2. Subuilder plugin.xml 摘录
<extension point = "com.ibm.etools.rsc.sp">
<sp
id = "com.ibm.etools.subuilder.sp.NewSQLSPAction"
name="%STR_NEWWIZARD_SQLSP"
group ="SPFolderAction.New"
view = "datadef"
class="com.ibm.etools.subuilder.actions.create.NewSQLSPAction"/>
</extension>
就参数而言,这个扩展孝敬看起来雷同于用来界说菜单选项孝敬的 org.eclipse.ui.popupmenu 扩展点;更确切地说,它界说了一个标签(属性 “name”),位置(属性“group”),方针(属性“view”),尚有最出格的 ,处理惩罚措施(属性 “class”)。Eclipse 扩展与这个非凡实现的区别是, Eclipse 的扩展建设一个委派类作为菜单选项的署理。直到菜单选项真正被选择 时,相应的处理惩罚措施类才会被建设,因而延迟了包括此处理惩罚器类的插件的激活。将同样的署理计接应用到前面的例子中,J2EE 透视图的打开快了差不多 7 秒。建设 NewSQLSPAction 实例和激活包括它引用的类的插件的开销并没有消除,而 是改变为随取随付 (pay-as-you-go)。
竣事语
#p#分页标题#e#
此刻您应该知道为什么本文的子标题定为“乐成的骗局”了。这完全是为了 满意用户的期望,并让用户不去剖析您但愿他们不要去留意的对象。在这个特例 中,此刻启动更快了,可是稍后假如用户启用数据库东西,他们还要是支付同样 多的 CPU 开销。那是可以接管的,因为开销是以化整为零的方法支付,并且, 更重要的是,它使延迟更靠近用户期望支付价钱的相关行动。
记着,方针是 尽大概延迟代码的执行,不只因为它可以带来感受上机能的提 高,还因为最容易用于优化速度的代码是永远不执行的代码。Eclipse 的插件体 系布局让您可以容易地建设告竣此目标的扩展,Runtime Spy 辅佐您找到那些可 以对实现举办改造的景象。