申明:仅说明排除过程和解决思路哦,代码比较复杂,而且这种情况代码参考价值不大,思路可能有一些参考价值。
前言 :什么是StackOverflowError?
我们看一下维基百科是怎么解释的呢?
Stack overflow
In software, a stack overflow occurs if the call stack pointer exceeds the stack bound. The call stack may consist of a limited amount of address space, often determined at the start of the program. The size of the call stack depends on many factors, including the programming language, machine architecture, multi-threading, and amount of available memory. When a program attempts to use more space than is available on the call stack (that is, when it attempts to access memory beyond the call stack’s bounds, which is essentially a buffer overflow), the stack is said to overflow, typically resulting in a program crash。(在软件中,如果调用堆栈指针超出堆栈界限,就会发生堆栈溢出。调用堆栈可能包含有限数量的地址空间,通常在程序开始时确定。调用堆栈的大小取决于许多因素,包括编程语言、机器体系结构、多线程和可用内存量。当程序尝试使用比调用堆栈上的可用空间更多的空间时(即,当它尝试访问超出调用堆栈边界的内存时,这本质上是缓冲区溢出),则称堆栈溢出,通常会导致程序崩溃。)
简单了解一下之后,看看我遇到的问题。
1.出现问题
公司有个项目用到了Activiti 工作流,有一天同事在查询某一项流程的审批历史时候,就出现了StackOverflowError的问题。
2.问题排查
出现问题的地方是 查询审批历史的接口,我跟代码时候发现里面是一个递归,但是呢,代码写的有一些问题,可能出现以下情况:
- 死循环
- 由于是递归,当审批流程足够负责,就会出现栈溢出的情况
- 还有其他各种问题,但是跟题目不相关,忽略 哈哈哈哈
3.处理思路
- 死循环的地方那肯定要解决的。
- 对于递归这块逻辑,审批流程如果复杂,那可能会出现问题,我用的方法是用迭代的方式去替换递归,我用了deque (double ended queue)双端队列 来实现迭代。这样可以避免在调用栈上不断累积方法调用,从而减少了堆栈溢出的风险。
这个确实仅仅是记录一下。比较水,哈哈哈哈。 这篇就水一下,后面的文章用心写。