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[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 -jar 内存溢出_JAVA系统启动栈内存溢出-StackOverflowError相关推荐

  1. java线程内存溢出_Java常见问题分析(内存溢出、内存泄露、线程阻塞等)

    Java垃圾回收机制(GC) 1.1 GC机制作用 1.2 堆内存3代分布(年轻代.老年代.持久代) 1.3 GC分类 1.4 GC过程 Java应用内存问题分析 2.1 Java内存划分 2.2 J ...

  2. java 内存溢出和内存泄漏_JAVA中的内存溢出和内存泄漏有很大的区别

    JAVA中的内存溢出和内存泄漏分别是什么,有什么联系和区别,我谈谈自己的理解. 内存泄漏(memory leak ):申请了内存不释放,比如100m的内存,分配了10m的内存一直不回收,那么可以用的内 ...

  3. java中栈和堆都存哪些东西_java中栈内存与堆内存(JVM内存模型)

    java中栈内存与堆内存(JVM内存模型) Java中堆内存和栈内存详解1 和 Java中堆内存和栈内存详解2 都粗略讲解了栈内存和堆内存的区别,以及代码中哪些变量存储在堆中.哪些存储在栈中.内存中的 ...

  4. java 堆内存和栈内存的区别_java中栈内存和堆内存有什么区别

    栈内存和堆内存的区别: 1.栈内存用来存放基本类型的变量和引用变量,堆内存用来存储java中的对象,无论是成员变量,局部变量,还是类变量,他们指向的对象都存储在堆内存中. (视频教程推荐:java视频 ...

  5. java如何避免内存溢出_java怎样防止内存溢出

    引起内存溢出的原因有很多种,小编列举一下常见的有以下几种: 1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据: 2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收: 3.代码中存 ...

  6. JAVA虚拟机 安全区域_Java虚拟机的内存区域

    2020年12月10日 阅读 186 关注 Java虚拟机的内存区域 最近在看<深入理解Java虚拟机>,故此写下自己的学习笔记. JVM 运行时数据区域 Java 虚拟机在执行 Java ...

  7. java final内存机制_Java中的内存处理机制和final、static、final static总结

    装载自:http://blog.csdn.net/wqthaha/article/details/20923579 Java程序运行在JVM上,可以把JVM理解成Java程序和操作系统之间的桥梁,JV ...

  8. java 内存情况_java查看jvm内存使用情况

    java查看jvm内存使用情况 (2012-03-22 15:50:54) 标签: jvm 内存 虚拟机 分配 it java.lang.Runtime类提供了查看当前JVM内存的使用情况.每个jav ...

  9. java static内存泄漏_Java中的内存泄漏

    内存泄漏是指不再使用的对象持续占有内存空间而得不到及时释放,从而造成内存空间的浪费称为内存泄漏.比如,长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是 ...

最新文章

  1. 微软无解!Win10用户突然减少:装回Win7
  2. Oracle NULL 和空值
  3. 深度学习和浅层学习 Deep Learning and Shallow Learning
  4. 用户体验改善案例_改善用户体验研究的5种习惯
  5. centos7,google身份验证
  6. 嘉善 机器人比赛_电脑机器人比赛辅导教师培训在浙师大嘉善附校举行
  7. 用c语言计算星期,计算任何一天是星期几的C语言源代码.
  8. 数据挖掘实践(金融风控)——task02:数据分析
  9. dorado 7 使用总结
  10. 设计模式--迭代器模式(C++实现)
  11. google浏览器更新问题和路径问题
  12. OpenCv —— 人脸识别(附完整源码)
  13. 硬盘分区之MBR讲解
  14. Ring3加载驱动源码
  15. JAVA 仿QQ聊天程序(附源码)
  16. C++卡常数之内存优化
  17. Ant Design表格插入图片
  18. 数字电路:边沿触发的D触发器简析
  19. Angular入门到精通系列教程(15)- 目录结构(工程结构)推荐
  20. 箱形图 python_Python-箱形图

热门文章

  1. res.status === 200含义
  2. A. Arithmetic Array Codeforces Round #726 (Div. 2)
  3. php科学计数法转string,php如何将科学计数法转数字
  4. c++ qt5范例开发大全_使用yocto工具编译qt5.9.6总结
  5. java处理中文字符串_Java实现读取文章中重复出现的中文字符串
  6. Qt+VS2005(配置步骤)
  7. 安装配置opensips过程记录
  8. python ddos攻击脚本_python版本DDOS攻击脚本
  9. python入侵数据库数据库_一个简单的Python访问Mysql数据库例子
  10. python简单应用题_Python简单应用题