你真的会看异常堆栈信息么( 二 )


其实“... n more”的部分是重复的堆栈部分 。我们分析一下上面这个函数“printEnclosedStackTrace” , 翻译为“打印封闭堆栈跟踪信息” , “封闭”暂且可以理解为“完整的” , 这个函数有两个比较重要的变量 , 分别是“enclosingTrace”和“trace ” , 这两个参数是什么关系呢?其实可以简单理解为“enclosingTrace”是“trace ”的父级堆栈 , 函数printEnclosedStackTrace中的while循环 , 就是为倒序找出“enclosingTrace”和“trace ”中从哪一个栈帧开始就不一样了 , 即“enclosingTrace”和“trace ”是有一部分是一样的(从数组后面倒回来) , 就是为了算出有多少个栈帧信息是重复可以隐藏的 , 相同的栈帧就不用重复输出啦 。下图就是第12行“... 2 more”隐藏的栈帧信息:

你真的会看异常堆栈信息么

文章插图
调试信息
按照上面的堆栈输出 , 第12行“... 2 more”隐藏2行堆栈信息 , 其实就是第7和第8行的栈帧信息;然后第8行“ ... 1 more”隐藏的1个堆栈信息 , 其实就是第4行的那个栈帧 。这样应该好理解了吧 , 每个异常都输出一个完整的堆栈信息的话 , 都是从main函数开始 , 到当前的函数的所有函数调用的栈帧信息 , 里面函数的调用栈帧信息都会包括外层的函数调用栈帧信息 , 所以都输出的话 , 很多都是重复的 , 为了提高效率 , 减少io以及输出的内容太多又杂乱 , 所以jvm以“... n more”的方式隐藏了重复的部分 。
当然 , 如果想不隐藏 , 可以重写java.lang.Throwable#printEnclosedStackTrace , 去掉while部分 , 就可以看到每个异常的完整堆栈信息了 , 可以参考https://blog.csdn.net/michaelehome/article/details/79484722来验证 。
 
参考:
https://www.jianshu.com/p/9f902c5517f8
https://blog.csdn.net/michaelehome/article/details/79484722

【你真的会看异常堆栈信息么】


推荐阅读