Eclipse作为一款日常工作中的主要IDE工具,由于安装的插件比较大或者代码比较多,因此听过不少人对其抱怨运行速度的不满(虽然现主很多人转投Intellij IDEA,但是依然有很多人或者公司在使用Eclipse作为开发工具)。趁着空闲机会,决定对Eclipse“动刀”了。

首先查看一些Eclipse启动的配置文件eclipse.ini可以看到我的Eclipse的配置设置了最大堆为1024m(1G),同时我的机器的运行环境是64位的Win10系统,硬件为神舟战神z7,I7处理器,8GB物理内存,使用的jdk是1.8版本。

由于我的Eclipse上没有装载其他插件,所以插件部分先不考虑进来。同时,众所周知升级jdk也能带来性能的提升,这里我也不升级演示了。

为了比较准确地统计Eclipse的启动时间,我这里写了一个插件,功能很简单就是统计Eclipse的启动耗时。(对于eclipse RCP开发感兴趣的可以自己去学习一下,这里就不再详细讲解了)插件代码如下:

将这个插件打包成jar以后放到Eclipse的dropins目录下即可,然后多次重启eclipse得到eclipse的启动时间稳定在13秒左右。

通过visualVm工具可以得到eclipse内存使用以及垃圾回收的初始数据,为了避免操作系统未能及时进行磁盘缓存而产生的影响,这里的数据取的是多次重启eclipse直到测试结果稳定后,取最后一次运行结果作为数据样本。(visualVm是jdk自带的一个多功能性能监控工具,其有许多插件,如果感兴趣并且能连上网的朋友可以自行下载。提示:visualVm如果不下载任何插件的话,虽然能显示一些基本的性能信息,但是很多信息无法查看,对于这样的visualVm基本上作用不大)。

从visualVm何eclipse插件收集的信息可以总结为以下几点:

1、整个启动过程平均耗时约为13秒

2、最后一次启动的数据样本中,垃圾回收的总耗时为0.429秒,其中:

Full GC被触发0次,共耗时0秒

Minor GC被触发29次,共耗时0.429秒

3、加载类19053个,耗时11.102秒

4、JIT编译时间为47.272秒

客观来说,由于机器硬件不错,13秒的启动时间其实还是在可以接受的范围之内,但是可以看到类加载时间以及JIT编译时间都比较长,还有新生代的垃圾回收时间占用了近半秒,我们后面看一下它是否可以优化。

首先从编译时间和类加载时间去做一个优化。

Java虚拟加的类加载的过程为:装载->链接(验证->准备->解析)->初始化,考虑到Eclipse的使用者甚多,它的编译代码我们认为都是可靠的,不需要在加载的时候进行字节码验证,因此可以试试加入参数-Xverify:none禁止掉字节码验证过程。加入参数后可以看到启动时间从平均13秒下降到8.78秒,可以看到这个效果还是非常明显的。

然后还有就是JIT编译的时间比较长,JIT就是Java虚拟机内置的两个运行时编译器,如果Java方法的调用次数达到一定程度,就会被判断为热点代码交给JIT 编译器即时编译为本地代码,以提高运行速度。由于它是运行时编译,并且会采集运行时数据,所以它编译出来的代码可能会比C/C++更加优秀。而其的一个最大的缺点就是编译需要消耗程序正常运行的时间,也就是上面所说的“编译时间”。

虚拟机提供了一个参数-Xint禁止编译器运行,我们来看看如果我们禁用动态编译后的启动时间。

结果不出所料,启动时间去到了24秒!由此可见,Java虚拟机的动态编译的确为程序的性能带来了不少的提高。除此之外,Java虚拟机还提供了更加强力的编译器:当虚拟机运行在-client模型的时候,使用的是一个代号为C1的轻量级编译器。另外还有一个代号为C2的相对重量的编译器能够提供更多的优化措施,如果使用-server模式启动eclipse并且长时间不关闭eclipse的话,虽然启动时间会比较长,但是C2编译器会将代码编译得更为彻底,所以C2所消耗的额外编译时间会从以后的运行速度提升中赚回来。不过现在还是继续以-client虚拟机启动Eclipse。

最后来看一下垃圾回收的优化部分。

由于程序启动后没有出现FUll GC,这说明老年代的容量还是比较充足的,新生代的对象都符合朝生夕灭的现象。基本上比较正常,没有需要调优的部分。但是Eclipse是用来写代码的,并不是用来测试启动速度的。我们不妨用测试一下eclipse进行代码编译运行数据。从下图我们可以看到有44次的Minor GC,耗时0.642秒。

再看一下CPU资源的使用情况,可以看到CPU的使用情况平均不到25%,垃圾回收的曲线可以说几乎看不到。

由于eclipse是与用户交互较多的应用程序,为了减少Minor GC的停顿时间我们可以将垃圾回收器设置为CMS垃圾回收期,增加参数配置:-XX:UseConMarkSweepGC。

设置完后可以看到Eden区的垃圾回收时间从642.493毫秒变成288.65毫秒(后来尝试了一下代码编译的效果,果然比加参数前快了许多),还是有点效果的。到此,对于虚拟机内存调优基本结束了(由于机器性能比较好,而且也没有特别耗资源的项目,所以可以调优的地方不多,后期有机会则会重新更新一篇关于垃圾回收调优的文章以弥补这篇文章的不足)。最后,虚拟机的调优参数如下:

参考书籍:《深入理解Java虚拟机》