某工程,注入变量都加了@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,正常了。
|