优化之误

优化之误!

如果在jvm启动时load飙高,然后逐渐正常的情况 ,我们经常会怀疑到 JIT 编译的问题。

增加启动时编译的核心数肯定是一个有效的解决办法,但是这个参数在启动时设置后,如果正常运行时不需要这么多核来工作,

你又不能在jvm已经启动的情况下动态降低这个参数。

所以使用-XX:+TieredCompilation进行分层编译,可以缓解这个问题,事实上也有很多case使用这个参数解决了jvm启动时load飙高的问题。


但是,如果打开分层编译,c1,c2的编译结果会比未分层的c2结果占用更大的CodeCache,很可能会超过默认的96m空间。

即使没有占满CodeCache,如果一次回收的空间较大,比如回收后可用空间为30m,但是每次编译的代码只有几百字节到几k,那么可用空间将会严重碎片化。


更可悲的是jdk7中,维护这个可用空间的是一个链表,查询到一个特定大小的连续空间函数largest_free_block()是加锁的,用一个加锁的函数访问一个巨大的列表,

结果可想而知。


也就是说,如果你不小心使用了jdk7的没有patch过的版本,打开了 -XX:+TieredCompilation参数,它不但不能优化,反而会因为argest_free_block()占用掉整个cpu。


具体请看:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8006952

之所以查到这个bug,正是我们的一个应用踩到这个雷了,应用被-XX:+TieredCompilation参数拖死。


因为是虚拟机,我们现在的解决方法是在启动时动态分配给虚拟机更多的内核加快JIT编译,正常启动后将虚拟机内核数恢复正常。


版权声明:本文为博主原创文章,未经博主允许不得转载。