事情起于开发应用对依赖的三方包(apache等等)进行了升级后(主要是升级spring),CPU的使用率较原来大幅提升,几个应用提升50%-100%。
查找半天,对比每次版本的cpu火焰图,看不出有什么不同,找不出cpu是哪些方法消耗了更多。(图中右下角有GC的方法,可能占比cpu总消耗太小了,真看不出什么)
局限于async-profiler采样的原理,cpu火焰图只能通过对比找出使用cpu高方法,方法占用的宽度越大,说明使用的cpu比率越大,就是消耗CPU的大户。
但,如果所有的方法是几乎等比例地提高了cpu使用率,那就无法判断是什么方法占用了更多的cpu了!如apache.commom; HashMap等,这些方法在火焰图的最上方部分,是java比较底层的方法。
===================================
突破的线索起于看到jstat -gcutil pid结果,在GCT这列看到总的消耗时间较前版本明显多了。(20分钟的压测明显多了1-2秒),没有FullGC,完全是YGC消耗了。
于是我意识到,肯定是JVM创建回收的对象多了!
于是我想到使用async-profiler 的alloc的模式,对不同的包进行采样,得出下面两图,原因就找到了。
cpu mode下的GC,确实没看出什么。
如下两图是alloc采样: