java.lang.StackOverflowError——因为设置Xss不恰当而导致的虚拟机栈溢出

本文介绍了由于不合适的-Xss参数导致的Java虚拟机栈溢出问题。在排查过程中,通过检查堆栈信息和JVM参数,发现问题源于-Xss设置。移除该参数并采用默认值后,问题得到解决。文章强调了调整Xss值的谨慎性,过大可能减少线程数,过小则可能导致栈空间不足。

一、问题现象

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'excelResultManager' defined in URL [file:/home/v5/ApacheJetspeed/webapps/seeyon/WEB-INF/cfgHome/spring/spring-reportengine-manager.xml]: Initialization of bean failed; nested exception is java.lang.StackOverflowError
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527) ~[spring-beans.jar:3.2.18.RELEASE]
	================
	中间内容不再截取
	================
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) ~[spring-beans.jar:3.2.18.RELEASE]
	at org.springframework.beans.factory.support.CTPBeanFactory$1.getObject(CTPBeanFactory.java:165) ~[seeyon-ctp-core.jar:3.2.18.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) ~[spring-beans.jar:3.2.18.RELEASE]
	at org.springframework.beans.factory.support.CTPBeanFactory.doGetBean(CTPBeanFactory.java:162) ~[seeyon-ctp-core.jar:3.2.18.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191) ~[spring-beans.jar:3.2.18.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:638) ~[spring-beans.jar:3.2.18.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942) ~[spring-context.jar:3.2.18.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) ~[spring-context.jar:3.2.18.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651) ~[spring-webmvc.jar:?]
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:602) ~[spring-webmvc.jar:?]
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665) ~[spring-webmvc.jar:?]
	at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:521) ~[spring-webmvc.jar:?]
	at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:462) ~[spring-webmvc.jar:?]
	at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136) ~[spring-webmvc.jar:?]
	at javax.servlet.GenericServlet.init(GenericServlet.java:158) ~[servlet-api.jar:3.1.FR]
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1144) ~[catalina.jar:8.5.35]
	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1091) ~[catalina.jar:8.5.35]
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:983) ~[catalina.jar:8.5.35]
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4978) ~[catalina.jar:8.5.35]
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5290) ~[catalina.jar:8.5.35]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ~[catalina.jar:8.5.35]
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754) ~[catalina.jar:8.5.35]
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730) ~[catalina.jar:8.5.35]
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734) ~[catalina.jar:8.5.35]
	at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1140) ~[catalina.jar:8.5.35]
	at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1875) ~[catalina.jar:8.5.35]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_202]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_202]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_202]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_202]
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_202]
Caused by: java.lang.StackOverflowError
	at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:153) ~[?:1.8.0_202]
	at java.lang.StringCoding.decode(StringCoding.java:193) ~[?:1.8.0_202]
	at java.lang.String.<init>(String.java:426) ~[?:1.8.0_202]
	at java.lang.String.<init>(String.java:491) ~[?:1.8.0_202]
	at java.io.UnixFileSystem.canonicalize0(Native Method) ~[?:1.8.0_202]
	at java.io.UnixFileSystem.canonicalize(UnixFileSystem.java:172) ~[?:1.8.0_202]
	at java.io.File.getCanonicalPath(File.java:618) ~[?:1.8.0_202]
	at org.apache.catalina.webresources.AbstractFileResourceSet.file(AbstractFileResourceSet.java:90) ~[catalina.jar:8.5.35]
	at org.apache.catalina.webresources.DirResourceSet.getResource(DirResourceSet.java:101) ~[catalina.jar:8.5.35]
	at org.apache.catalina.webresources.StandardRoot.getResourceInternal(StandardRoot.java:281) ~[catalina.jar:8.5.35]
	at org.apache.catalina.webresources.Cache.getResource(Cache.java:62) ~[catalina.jar:8.5.35]
	at org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:216) ~[catalina.jar:8.5.35]
	at org.apache.catalina.webresources.StandardRoot.getClassLoaderResource(StandardRoot.java:225) ~[catalina.jar:8.5.35]
	at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2278) ~[catalina.jar:8.5.35]
	at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:830) ~[catalina.jar:8.5.35]
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1297) ~[catalina.jar:8.5.35]
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1156) ~[catalina.jar:8.5.35]
	at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_202]
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[?:1.8.0_202]
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.8.0_202]
	at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2356) ~[catalina.jar:8.5.35]
	at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:830) ~[catalina.jar:8.5.35]
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1297) ~[catalina.jar:8.5.35]
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1156) ~[catalina.jar:8.5.35]
	at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_202]
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[?:1.8.0_202]
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.8.0_202]
	at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2356) ~[catalina.jar:8.5.35]
	at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:830) ~[catalina.jar:8.5.35]
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1297) ~[catalina.jar:8.5.35]
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1156) ~[catalina.jar:8.5.35]
	at java.lang.Class.getDeclaredMethods0(Native Method) ~[?:1.8.0_202]
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[?:1.8.0_202]
	at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[?:1.8.0_202]
	at org.springframework.cglib.core.ReflectUtils.addAllMethods(ReflectUtils.java:348) ~[spring-core.jar:3.2.18.RELEASE]
	at org.springframework.cglib.proxy.Enhancer.getMethods(Enhancer.java:421) ~[spring-core.jar:3.2.18.RELEASE]
	at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:456) ~[spring-core.jar:3.2.18.RELEASE]
	at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33) ~[spring-core.jar:3.2.18.RELEASE]
	at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) ~[spring-core.jar:3.2.18.RELEASE]
	at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) ~[spring-core.jar:3.2.18.RELEASE]
	at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) ~[spring-core.jar:3.2.18.RELEASE]
	at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285) ~[spring-core.jar:3.2.18.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:206) ~[spring-aop.jar:3.2.18.RELEASE]
	at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109) ~[spring-aop.jar:3.2.18.RELEASE]
	at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:479) ~[spring-aop.jar:3.2.18.RELEASE]
	at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:364) ~[spring-aop.jar:3.2.18.RELEASE]
	at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:324) ~[spring-aop.jar:3.2.18.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:409) ~[spring-beans.jar:3.2.18.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1520) ~[spring-beans.jar:3.2.18.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) ~[spring-beans.jar:3.2.18.RELEASE]
	... 631 more

二、问题排查

  1. 检查输出的堆栈信息,可以确定是Spring递归创建Spring Bean对象的过程,检查发现我们最近并没有对spring加载这块做什么配置修改,暂时可以排除是Spring代码原因;
  2. 检查Tomcat启动的JVM参数,发现除了常规设置的最大内存最小内存最大元内存等,还有一个-Xss,我把目标盯在他上面了。
-Xms1280m -Xmx1280m -Xss256k -XX:NewSize=384M -XX:MaxNewSize=384M -XX:MaxMetaspaceSize=512m -XX:SurvivorRatio=32 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:TargetSurvivorRatio=50
  1. 将配置中的-Xss参数去掉(采用JVM默认值),最终修改后参数如下:
-Xms1280m -Xmx1280m -XX:MaxMetaspaceSize=384m -XX:SurvivorRatio=32 -XX:+UseG1GC
  1. 重启Tomcat,能正常启动,跟踪多次并没有再出现。

三、StackOverflowError异常

导致StackOverFlowError异常有两种原因:

  1. 递归调用的层次过多——要好好检查下代码了;
  2. 设置的Xss值不足以实际虚拟机栈使用——调整Xss值;

四、总结

  1. Xss设置还需谨慎,设置大了可开启的线程数少,设置小了又不够用;

五、参考链接

  1. java.lang.StackOverflowError
  2. JVM优化系列之一(-Xss调整Stack Space的大小)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值