|
有一个专门处理任务型的应用发现有停止处理业务逻辑。 通过top看到,系统几个核CPU占用率非常高(100%),且不处理正常业务: top - 03:07:48 up 232 days, 5:14, 2 users, load average: 3.77, 3.49, 3.43 Tasks: 127 total, 1 running, 126 sleeping, 0 stopped, 0 zombie Cpu0 : 10.6%us, 0.3%sy, 0.0%ni, 89.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu1 : 0.0%us, 0.0%sy, 0.0%ni, 98.7%id, 1.3%wa, 0.0%hi, 0.0%si, 0.0%st Cpu2 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu3 :100.0%us, 0.0%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu4 :100.0%us, 0.0%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu5 : 0.0%us, 0.3%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu6 :100.0%us, 0.0%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu7 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 10485760k total, 9227556k used, 1258204k free, 201184k buffers Swap: 2097144k total, 116k used, 2097028k free, 1643884k cached 从上面top数据可以看到,有三个核 CPU3,4,6 占用的CPU一直是 100%,那发生了什么事情呢? 接着使用jtop查看,命令如下: java -jar jtop.jar -thread 3 -stack 8 <PID> 2000 100 得到的输出如下: DefaultQuartzScheduler_Worker-8 TID=86 STATE=RUNNABLE CPU_TIME=2110 (99.90%) USER_TIME=2110 (99.90%) Allocted: 0 java.util.WeakHashMap.put(WeakHashMap.java:405) org.aspectj.weaver.Dump.registerNode(Dump.java:253) org.aspectj.weaver.World.<init>(World.java:150) org.aspectj.weaver.reflect.ReflectionWorld.<init>(ReflectionWorld.java:50) org.aspectj.weaver.tools.PointcutParser.setClassLoader(PointcutParser.java:221) org.aspectj.weaver.tools.PointcutParser.<init>(PointcutParser.java:207) org.aspectj.weaver.tools.PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution(PointcutParser.java:128) org.springframework.aop.aspectj.AspectJExpressionPointcut.<init>(AspectJExpressionPointcut.java:100) DefaultQuartzScheduler_Worker-10 TID=88 STATE=RUNNABLE CPU_TIME=2110 (99.90%) USER_TIME=2110 (99.90%) Allocted: 0 java.util.WeakHashMap.put(WeakHashMap.java:405) org.aspectj.weaver.Dump.registerNode(Dump.java:253) org.aspectj.weaver.World.<init>(World.java:150) org.aspectj.weaver.reflect.ReflectionWorld.<init>(ReflectionWorld.java:50) org.aspectj.weaver.tools.PointcutParser.setClassLoader(PointcutParser.java:221) org.aspectj.weaver.tools.PointcutParser.<init>(PointcutParser.java:183) org.aspectj.weaver.reflect.InternalUseOnlyPointcutParser.<init>(InternalUseOnlyPointcutParser.java:22) org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate.getDeclaredPointcuts(Java15ReflectionBasedReferenceTypeDelegate.java:243) DefaultQuartzScheduler_Worker-6 TID=84 STATE=RUNNABLE CPU_TIME=2100 (99.43%) USER_TIME=2100 (99.43%) Allocted: 0 java.util.WeakHashMap.put(WeakHashMap.java:405) org.aspectj.weaver.Dump.registerNode(Dump.java:253) org.aspectj.weaver.World.<init>(World.java:150) org.aspectj.weaver.reflect.ReflectionWorld.<init>(ReflectionWorld.java:50) org.aspectj.weaver.tools.PointcutParser.setClassLoader(PointcutParser.java:221) org.aspectj.weaver.tools.PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution(PointcutParser.java:129) org.springframework.aop.aspectj.AspectJExpressionPointcut.<init>(AspectJExpressionPointcut.java:100) org.springframework.aop.aspectj.AspectJExpressionPointcut.<init>(AspectJExpressionPointcut.java:109) 发现这一行 java.util.WeakHashMap.put(WeakHashMap.java:405)消耗CPU极高,接近100%, 通过查看JDK源代码,看到: 399. public V put(K key, V value) {
400. K k = (K) maskNull(key);
401. int h = HashMap.hash(k.hashCode());
402. Entry[] tab = getTable();
403. int i = indexFor(h, tab.length);
404.
405. for (Entry<K,V> e = tab[i]; e != null; e = e.next) {
406. if (h == e.hash && eq(k, e.get())) {
407. V oldValue = e.value;
408. if (value != oldValue)
409. e.value = value;
410. return oldValue;
411. }
412. }
413.
414. modCount++;
415. Entry<K,V> e = tab[i];
416. tab[i] = new Entry<K,V>(k, value, queue, h, e);
417. if (++size >= threshold)
418. resize(tab.length * 2);
419. return null;
420. }
从这里我们知道WeakHashMap是线程不安全的,而且这个版本的aspectj没有很好的使用这个类,再通过jstack查看完整的堆栈信息: java.lang.Thread.State: RUNNABLE
at java.util.WeakHashMap.put(WeakHashMap.java:405)
at org.aspectj.weaver.Dump.registerNode(Dump.java:253)
at org.aspectj.weaver.World.<init>(World.java:150)
at org.aspectj.weaver.reflect.ReflectionWorld.<init>(ReflectionWorld.java:50)
at org.aspectj.weaver.tools.PointcutParser.setClassLoader(PointcutParser.java:221)
at org.aspectj.weaver.tools.PointcutParser.<init>(PointcutParser.java:183)
at org.aspectj.weaver.reflect.InternalUseOnlyPointcutParser.<init>(InternalUseOnlyPointcutParser.java:22)
at org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate.getDeclaredPointcuts(Java15ReflectionBasedRef
erenceTypeDelegate.java:243)
at org.aspectj.weaver.ReferenceType.getDeclaredPointcuts(ReferenceType.java:740)
at org.aspectj.weaver.ResolvedType$7.get(ResolvedType.java:531)
at org.aspectj.weaver.ResolvedType$7.get(ResolvedType.java:528)
at org.aspectj.weaver.Iterators$3$1.hasNext(Iterators.java:128)
at org.aspectj.weaver.Iterators$3.hasNext(Iterators.java:144)
at org.aspectj.weaver.ResolvedType.findPointcut(ResolvedType.java:539)
at org.aspectj.weaver.patterns.ReferencePointcut.resolveBindings(ReferencePointcut.java:149)
at org.aspectj.weaver.patterns.Pointcut.resolve(Pointcut.java:196)
at org.aspectj.weaver.tools.PointcutParser.resolvePointcutExpression(PointcutParser.java:314)
at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:295)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:15
9)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:149)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:134)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:165)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:225)
at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:255)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAut
oProxyCreator.java:73)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAd
visorAutoProxyCreator.java:57)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoPro
xyCreator.java:255)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitializa
tion(AbstractAutowireCapableBeanFactory.java:312)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapable
BeanFactory.java:1033)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBean
Factory.java:421)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:156)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:640)
知道问题原因那么解决就简单了,原本想通过升级aspectj来解决,但因为一些特殊的历史原因无法简单的通过升级来解决,然后就采用了一种比较简单的解决方案,将调用spring的getBean的方法加上了synchronized修饰,问题解决。 |