| 
某工程,注入变量都加了@Lazy后,压测性能下降很多。  
 用jprofiler抓,发现很多方法调用很卡,但实际业务只有毫秒级,但整体调用却几十秒。
 
 jp只能看到是拦截器耗时,具体什么无法展开。
 77.7% - 1,529 s org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept
 所以,推测是拦截器本身耗时。
 
 没想法,后来发现耗时的Service比较特别
 @Service
 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
 不是单例模式,是每次getBean都新创建一个实例。
 
 jp抓cpu看不出,我就不停地点dump堆栈,然后对照着看。
 
 java.lang.Class.getDeclaredConstructors0(boolean)
 java.lang.Class.privateGetDeclaredConstructors(boolean)
 java.lang.Class.getConstructor0(java.lang.Class[ ], int)
 java.lang.Class.newInstance()
 sun.reflect.MethodAccessorGenerator$1.run()
 sun.reflect.MethodAccessorGenerator$1.run()
 java.security.AccessController.doPrivileged(java.security.PrivilegedAction)
 sun.reflect.MethodAccessorGenerator.generate(java.lang.Class, java.lang.String, java.lang.Class[ ], java.lang.Class, java.lang.Class[ ], int, boolean, boolean, java.lang.Class)
 sun.reflect.MethodAccessorGenerator.generateSerializationConstructor(java.lang.Class, java.lang.Class[ ], java.lang.Class[ ], int, java.lang.Class)
 sun.reflect.ReflectionFactory.newConstructorForSerialization(java.lang.Class, java.lang.reflect.Constructor)
 sun.reflect.GeneratedMethodAccessor5784.invoke(java.lang.Object, java.lang.Object[ ])
 sun.reflect.DelegatingMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[ ])
 java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[ ])
 org.springframework.objenesis.instantiator.sun.SunReflectionFactoryHelper.newConstructorForSerialization(java.lang.Class, java.lang.reflect.Constructor) (line: 45)
 org.springframework.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.<init>(java.lang.Class) (line: 38)
 org.springframework.objenesis.strategy.StdInstantiatorStrategy.newInstantiatorOf(java.lang.Class) (line: 58)
 org.springframework.objenesis.ObjenesisBase.getInstantiatorOf(java.lang.Class) (line: 91)
 org.springframework.objenesis.ObjenesisBase.newInstance(java.lang.Class) (line: 73)
 org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(org.springframework.cglib.proxy.Enhancer, org.springframework.cglib.proxy.Callback[ ]) (line: 57)
 org.springframework.aop.framework.CglibAopProxy.getProxy(java.lang.ClassLoader) (line: 202)
 org.springframework.aop.framework.ProxyFactory.getProxy(java.lang.ClassLoader) (line: 109)
 org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver.buildLazyResolutionProxy(org.springframework.beans.factory.config.DependencyDescriptor, java.lang.String) (line: 94)
 org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver.getLazyResolutionProxyIfNecessary(org.springframework.beans.factory.config.DependencyDescriptor, java.lang.String) (line: 44)
 org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(org.springframework.beans.factory.config.DependencyDescriptor, java.lang.String, java.util.Set, org.springframework.beans.TypeConverter) (line: 947)
 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(org.springframework.beans.factory.BeanFactory, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$LookupElement, java.lang.String) (line: 439)
 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$LookupElement, java.lang.String) (line: 417)
 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(java.lang.Object, java.lang.String) (line: 542)
 org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(java.lang.Object, java.lang.String, org.springframework.beans.PropertyValues) (line: 155)
 org.springframework.beans.factory.annotation.InjectionMetadata.inject(java.lang.Object, java.lang.String, org.springframework.beans.PropertyValues) (line: 87)
 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(org.springframework.beans.PropertyValues, java.beans.PropertyDescriptor[ ], java.lang.Object, java.lang.String) (line: 304)
 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, org.springframework.beans.BeanWrapper) (line: 1204)
 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[ ]) (line: 538)
 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[ ]) (line: 476)
 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(java.lang.String, java.lang.Class, java.lang.Object[ ], boolean) (line: 321)
 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(java.lang.String) (line: 193)
 org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(java.lang.String, java.lang.Class, org.springframework.beans.factory.config.DependencyDescriptor) (line: 1127)
 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(org.springframework.beans.factory.config.DependencyDescriptor, java.lang.String, java.util.Set, org.springframework.beans.TypeConverter) (line: 1051)
 org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver$1.getTarget() (line: 82)
 org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.getTarget() (line: 685)
 org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[ ], org.springframework.cglib.proxy.MethodProxy) (line: 636)
 cn.com.xxx.service.SettlementServiceImpl$$EnhancerBySpringCGLIB$$119646f1.yyyySettle(cn.com.xxx.settlement.xxxxParams, cn.com.xxx.model.xxBs, java.lang.Long, java.lang.Long)
 cn.com.xxx.BizAsyncSettlement.xxxBefore(cn.com.xxx.settlement.xxSettlementParams, cn.com.xxx.yySettleTask) (line: 2591)
 
 
 调用cn.com.xxx.service.SettlementServiceImpl$$EnhancerBySpringCGLIB$$119646f1.yyyySettle时,它是一个增强代理类,
 
 调getTarget(),就是找实际的service,
 
 由于该service不是单例,所以每次都new一个
 
 所以调用了AbstractAutowireCapableBeanFactory.createBean
 
 然后上面调了ContextAnnotationAutowireCandidateResolver.buildLazyResolutionProxy
 
 这是啥呢?
 
 搜了半天,原来变量注入使用@Lazy的话,
 
 spring会给这个变量做一个代理类,
 
 但是,这个service的注入变量有几十个,所以创建每次创建代理类就耗时了吧。
 
 尝试把@Lazy去掉,再抓cpu,正常了。
 |