最近自从eclipse安装了很多插件以后启动变得非常的慢每次启动要消耗近半分钟这是不正常的 今天决定好好优化一下
我所使用的eclipse是Eclipse Java EE IDE for Web Developers 版本 跑在MAC OSX上 SSD+G RAM 这么高性能的机器竟然不能秒开eclipse 这太说不过去了 哦还有我使用的JVM是Oracle的HotSpot来自于JDK bit
首先在优化前让我们看看eclipse启动时JVM的各项性能指标 因为我并不能准确的判定eclipse的启动完成时间 所以我只能说大约事件
首先启动JDK自带的JVM性能监视工具在java\bin的目录下有一个jvisualvm它是绑定在JDK中的visualvm双击启动 visualvm 然后启动eclipse 在eclipse启动完成以后使用visualvm的查看eclipse的Visual GC情况 如图:
上图中说明在eclipse的启动过程中JIT对字节码进行了向机器码的编译花去了秒的时间Class加载花去了秒的时间Minor GC发生了次花去秒Full GC发生了次仅仅花去了毫秒
我们再去MBean选项查看发现新生代使用ParNew垃圾收集器而老年代使用的是CMS垃圾收集器
总上情况看出由于MAC的性能比较好所以垃圾回收并没有消耗太多的时间并且CMS+ParNew本身就是并行垃圾回收不会造成用户程序太多的停顿 时间主要消耗在了JIT的即时编译和Class加载上了
首先要优化的就是class加栽因为eclipse这个工具是一个成熟的工具经过了这么多人的验证所以我充分信任eclipse的代码允许 eclipse的代码在加载的时候跳过字节码验证 关闭字节码验证的方法是在vm的args中加入参数 Xverify:none 对于eclipse来说找到eclipseini 加入Xverify:none 让我们再重启一下eclipse看看class加载时间是否减小 再次启动发现class加载事件缩小到秒比之前少了秒
然后优化的是JIT的时间 在使用eclipse编写程序时主要是文本编辑编译和运行JIT虽然可以带给我们高性能但是JIT在编译机器码的时候却要消耗很多的时间 eclipse对项目的编译和运行本身就很慢切运行时是启动一个新的java进程跟eclipse本身无关所以我可以接受抛弃JIT编译器而只是用JVM解释器执行字节码所带来的效率降低 这样可以去除JIT编译的时间 做法如下在eclipseini中加入vm的参数 Xint 意思是只使用解释器 让我们来看看结果:
JVM编译器时间变成了 一下减掉秒 但是由于缺少了运行时的即时编译优化方案代码的运行时间变长了 eclipse的整体启动时间慢了更多超过了秒 由此可见JIT是多么有用的一项技术所以禁止JIT的尝试失败了我们把之前的参数Xint去掉
哦对了我还装了很多的插件尤其是android开发插件启动的时候对插件的激活也会花去很多时间 屏蔽插件激活的方法: Windows > Preferences 输入 startup 点击 Startup and Shutdown 把不需要的插件勾掉 此外还需要关掉不必要的validation方法为:Windows > Preferences > Validation 只选你需要的
做完以上工作我发现eclipse启动稍微快了一些 掐着秒表计算的花了大约秒
最后再优化一下GC和堆栈吧虽然说GC已经表现的很好了都没有超过秒但是GC的频率如此高说明JVM的内存的分配是不合理的为此我们需要重新对JVM内存进行划分 为了对JVM的内存进行合理分配我们需要了解eclipse启动过程中GC到底发生了什么事情 打开gc log的方法如下:
想eclipseini的vm参数中添加
XX:+PrintGCDetails
Xloggc:/users/joey/Documents/gclog
启动eclipse生成gclog 打开log进行分析
第一次Minor GC发现新生代的大小约为M 堆的大小约为M 再接下来的GC中新生代始终没有扩容这说明新生代的大小合适
: [GC : [ParNew: K>K(K) secs] K>K(K) secs] [Times: user= sys= real= secs]
第一次发生Full GC时发现老年代已经扩容到约M而永生代扩容到约M
: [Full GC (System) : [CMS: K>K(K) secs] K>K(K) [CMS Perm : K>K(K)] secs] [Times: user= sys= real= secs]
而直到最后一次GC 老年代占用也没超过M永生带占用也没有超过M 但他们的占用空间均超过了M 由此我们有理由规定一个初始堆大小 最终通过分析我给eclipseini添加了如下几个参数:
server
Xverify:none
XX:PermSize=m
XX:MaxPermSize=m
Xmsm
Xmxm
Xmnm
Xssm
server是让JVM以server模式运行加重JIT的优化作用由于eclipse是经常开着不关在server模式下JIT会随着运行的时间把字节码更深刻的变成成机器代码加快运行速度
Xverify:none 跳过对字节码的验证
PermSize永生带设置为M堆的初始大小设置为M新生代站了M 每个线程栈大小设为M
在这种设置下Full GC已经完全消失但还是剩下了次左右的Minor GC大约花掉秒 这是可以接受的 如果为了完全消除GC而把新生代的空间设大那也是一种内存的浪费 重启eclipse启动时间已经落在了秒之内如图: