美文网首页
JAVA系统启动栈内存溢出-StackOverflowError

JAVA系统启动栈内存溢出-StackOverflowError

作者: 万福来 | 来源:发表于2020-05-15 11:08 被阅读0次

JAVA系统启动栈内存溢出-StackOverflowError

线上服务器启动报错日志如下:

Caused by: java.lang.IllegalStateException: Unable to complete the scan for annotations for web application [] due to a StackOverflowError. Possible root causes include a too low setting for -Xss and illegal cyclic inheritance dependencies. The class hierarchy being processed was [org.bouncycastle.asn1.ASN1EncodableVector->org.bouncycastle.asn1.DEREncodableVector->org.bouncycastle.asn1.ASN1EncodableVector]
at org.apache.catalina.startup.ContextConfig.checkHandlesTypes(ContextConfig.java:2066)
at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2012)
at org.apache.catalina.startup.ContextConfig.processAnnotationsJar(ContextConfig.java:1961)
at org.apache.catalina.startup.ContextConfig.processAnnotationsUrl(ContextConfig.java:1936)
at org.apache.catalina.startup.ContextConfig.processAnnotations(ContextConfig.java:1897)

看日志提示是-Xss参数设置过低引起的栈内存溢出,先解释下-Xss参数。

JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.更具应用的线程所需内存大小进行 调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右
一般小的应用, 如果栈不是很深, 应该是128k够用的 大的应用建议使用256k。
但是根据-Xss参数调整栈内存大小之后,再重新启动还是会StackOverflowError。所以栈内存设置过小不是根本原因。
再看下这个错误信息 StackOverflowError,抛出这个错误表明应用程序因为深递归导致栈被耗尽了。
StackOverflowError 是 VirtualMachineError 的扩展类,VirtualMachineError 表明 JVM 中断或者已经耗尽资源,无法运行。
而且,VirtualMachineError 类扩展自 Error 类,这个类用于指出那些应用程序不需捕获的严重问题。因为这些错误是在可能永远不会发生的异常情况下产生,所以方法中没有在它的 throw 语句中声明。

Java 里的 StackOverflowError
Java 应用程序唤起一个方法调用时就会在调用栈上分配一个栈帧, 这个栈帧包含引用方法的参数,本地参数,以及方法的返回地址。

这个返回地址是被引用的方法返回后程序能够继续执行的执行点。如果没有一个新的栈帧所需空间,Java 虚拟机就会抛出 StackOverflowError。

最常见的可能耗光 Java 应用程序的栈的场景是程序里的递归。递归时一个方法在执行过程中会调用自己。 递归被认为是一个强大的多用途编程技术,为了避免出现 StackOverflowError,使用时必须特别小心。

如何处理 StackOverflowError
最简单的解决方案是仔细检查输出信息中的栈路径,查明模式重复的代码行号。这些行号对应的代码被递归调用了。确认这些行后,你必须小心的检查你的代码,弄清楚为什么递归永远不结束。

如果你确认递归实现是正确的,为了允许大量的调用,你可以增加栈的大小。依赖于安装的 Java 虚拟机,默认的线程栈大小可能是 512KB 或者 1MB。你可以使用 -Xss 标识来增加线程栈的大小。这个标识即可以通过项目的配置也可以通过命令行来指定。

-Xss 参数的格式:-Xss<size>[g|G|m|M|k|K]

在看系统启动报错日志信息

The class hierarchy being processed was [org.bouncycastle.asn1.ASN1EncodableVector->org.bouncycastle.asn1.DEREncodableVector->org.bouncycastle.asn1.ASN1EncodableVector]

根据这段提示信息是ASN1EncodableVector 依赖了DEREncodableVector,DEREncodableVector后面又依赖了ASN1EncodableVector ,造成了死循环,导致栈内存消耗殆尽。
然后根据这个类名去项目中搜索查看类结构,根据类名搜索结果如下:
搜索到了两个一模一样的类,由于之前项目启动是没有问题的,而itext-asian-5.2.0.jar 也是最近添加的jar包依赖,所以猜测可能是两个jar包有相同包名的类,导致了死循环依赖,所以直接出现了栈内存溢出问题。

找到了相同的类,那就可以先把项目中没有使用到的bcprov-jdk15-1.43.jar进行排除掉,然后上线,系统启动正常,原来的栈内存溢出问题没有出现。

具体bcprov-jdk15-1.43.jar ASN1EncodableVector 源码如下:

package org.bouncycastle.asn1;
 
import org.bouncycastle.asn1.DEREncodableVector;
 
public class ASN1EncodableVector extends DEREncodableVector {
    public ASN1EncodableVector() {
    }
}

具体itext-asian-5.2.0.jar ASN1EncodableVector 源码如下:

package org.bouncycastle.asn1;
 
import org.bouncycastle.asn1.ASN1EncodableVector;
 
public class DEREncodableVector extends ASN1EncodableVector {
    /** @deprecated */
    public DEREncodableVector() {
    }
}

通过源码可以看到ASN1EncodableVector 和DEREncodableVector互为父类和子类,造成了死循环继承。 所以只需要将没有使用的一方jar包依赖排除即可

相关文章

  • JAVA系统启动栈内存溢出-StackOverflowError

    JAVA系统启动栈内存溢出-StackOverflowError 线上服务器启动报错日志如下: 看日志提示是-Xs...

  • 虚拟机栈溢出

    错误原因:java.lang.StackOverflowError 栈内存溢出 栈溢出产生递归调用,循环遍历是不会...

  • java异常

    java. lang. Throwable Error:错误 栈溢出:stackoverflowerror 堆溢出...

  • 词汇量

    StackOverflowError 内存栈溢出 disk 磁盘 content 内容 virtual 虚拟 de...

  • JVM整理

    JVM基本结构 Java栈:1.过多的线程或栈帧过多时会造成溢出StackOverflowError。2.Java...

  • Java栈溢出--StackOverflowError

    StackOverflowError原因  Java 里的 StackOverflowError。抛出这个错误表明...

  • JVM

    1、一般什么情况会发生栈溢出、堆溢出 栈溢出(StackOverflowError) 1、栈是线程私有的,他的生命...

  • 栈溢出 StackOverflowError

    问题 生产环境栈溢出 原因 递归调用次数太多导致且启动脚本中设置了-Xss 解决办法 由于涉及到的代码依赖较多,先...

  • 【笔记】深入理解 java 虚拟机---虚拟机内存溢出

    虚拟机的内存溢出有以下情况: 1 Java 堆内存溢出。 OutOfMemory。 2 栈内存溢出。StatckO...

  • JVM学习:虚拟机栈-相关面试题

    举例栈溢出的情况?(StackOverflowError) 通过 -Xss 设置栈的大小 调整栈大小,就能保证不出...

网友评论

      本文标题:JAVA系统启动栈内存溢出-StackOverflowError

      本文链接:https://www.haomeiwen.com/subject/tbaqohtx.html