5.3.1 调优前的程序运行状态

5.3.1 调优前的程序运行状态

笔者使用Eclipse作为日常工作中的主要IDE工具,由于安装的插件比较大(如Kloc-work、 ClearCase LT等)、代码也很多,启动Eclipse直到所有项目编译完成需要四五分钟。一直对开发环境的速度感觉到不满意,趁着编写这本书的机会,决定对Eclipse进行“动刀”调优。

笔者机器的Eclipse运行平台是32位Windows 7系统,虚拟机为HotSpot 1.5 b64。硬件为ThinkPad X201,Intel i5 CPU,4GB物理内存。在初始的配置文件eclipse.ini中,除了指定JDK的路径、设置最大堆为512MB以及开启了JMX管理(需要在VisualVM中收集原始数据)外,未作任何改动,原始配置内容如代码清单5-3所示。

代码清单5-3 Eclipse 3.5初始配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
D:/_DevSpace/jdk1.5.0/bin/javaw.exe 
-startup
plugins/org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.0.200.v20090519
-product
org.eclipse.epp.package.jee.product
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xmx512m
-Dcom.sun.management.jmxremote

为了与调优后的结果进行量化对比,调优开始前笔者先做了一次初始数据测试。测试用例很简单,就是收集从Eclipse启动开始,直到所有插件加载完成为止的总耗时以及运行状态数据,虚拟机的运行数据通过VisualVM及其扩展插件VisualGC进行采集。测试过程中反复启动数次Eclipse直到测试结果稳定后,取最后一次运行的结果作为数据样本(为了避免操作系统未能及时进行磁盘缓存而产生的影响),数据样本如图5-2所示。

image-20210919112606221

图5-2 Eclipse原始运行数据

Eclipse启动的总耗时没有办法从监控工具中直接获得,因为VisualVM不可能知道Eclipse运行到什么阶段算是启动完成。为了测试的准确性,笔者写了一个简单的Eclipse插件,用于统计Eclipse的启动耗时。由于代码十分简单,且本书并不是Eclipse RCP的开发教程,所以只列出代码清单5-4供读者参考,不再延伸。如果读者需要这个插件,可以使用下面的代码自己编译即可。

代码清单5-4 Eclipse启动耗时统计插件

ShowTime.java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
```java
/* ShowTime.java代码: */

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IStartup;

/*** 统计Eclipse启动耗时 * @author zzm */
public class ShowTime implements IStartup {
public void earlyStartup() {
Display.getDefault().syncExec(new Runnable() {
public void run() {
long eclipseStartTime = Long.parseLong(System.getProperty("eclipse.startTime"));
long costTime = System.currentTimeMillis() - eclipseStartTime;
Shell shell = Display.getDefault().getActiveShell();
String message = "Eclipse启动耗时:" + costTime + "ms";
MessageDialog.openInformation(shell, "Information", message);
}
});
}
}

plugin.xml代码:

1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.4"?>
<plugin>
<extension point="org.eclipse.ui.startup">
<startup class="eclipsestarttime.actions.ShowTime" />
</extension>
</plugin>

上述代码打包成JAR后放到Eclipse的plugins目录,反复启动几次后,插件显示的平均时间稳定在 15秒左右,如图5-3所示。

image-20210919113033359

图5-3 耗时统计插件运行效果
根据VisualGC和Eclipse插件收集到的信息,总结原始配置下的测试结果如下:

  • 整个启动过程平均耗时约15秒。
  • 最后一次启动的数据样本中,垃圾收集总耗时4.149秒,其中:
    • Full GC被触发了19次,共耗时3.166秒;
    • Minor GC被触发了378次,共耗时0.983秒。
  • 加载类9115个,耗时4.114秒。
  • 即时编译时间1.999秒。
  • 交给虚拟机的512MB堆内存被分配为40MB的新生代(31.5MB的Eden空间和2个4MB的Survivor 空间)以及472MB的老年代。

客观地说,考虑到该机器硬件的条件,15秒的启动时间其实还在可接受范围以内,但是从VisualGC中反映的数据上看,存在的问题是非用户程序时间(图5-2中的Compile Time、Class Load Time、GC Time)占比非常之高,占了整个启动过程耗时的一半以上(这里存在少许夸张成分,因为如即时编译等动作是在后台线程完成的,用户程序在此期间也正常并发执行,最多就是速度变慢,所
以并没有占用一半以上的绝对时间)。虚拟机后台占用太多时间也直接导致Eclipse在启动后的使用过程中经常有卡顿的感觉,进行调优还是有较大价值的。