示例
编写例子会有点难,因为我们很难在托管程序产生堆栈溢出的同时,还能有一部分空间来做些其他的事。在演示项目中,我提供了我认为最佳的解决方案,文中我没有做详细阐述,但我展示了一些以无法控制的形式不断溢出堆栈的代码,其对保留空间无任何作用。int depth;
@ReservedStackAccess
private void determineDepthWithReservedStack() {
determineDepth();
}
private void determineDepth() {
depth = 0;
try {
recurseToDetermineMaxDepth();
} catch (StackOverflowError err) { }
System.out.printf("Depth: %d%n", depth);
}
private void recurseToDetermineMaxDepth() {
depth++;
recurseToDetermineMaxDepth();
}
从下往上看,你会发现这是一个无限递归和递增 depth 字段的方法,只是用另外一种方式进行了包装,它能捕获异常并打印 depth 的值。最后,第三个方法请求访问保留堆栈区域。我并没有使用保留的堆栈区域,而是通过递归调用来将它耗尽。这意味着不管调用 determineDepth 还是 determineDepthWithReservedStack,最终都会导致堆栈的溢出,并打印出调用的次数。但输出结果会有所不同,如下:DEPTH USING REGULAR STACK
Depth: 21392
DEPTH USING RESERVED STACK
Java HotSpot(TM) 64-Bit Server VM warning: Potentially dangerous stack overflow in ReservedStackAccess annotated method org.codefx.demo.java9.internal.stack.ReservingStackAreas.determineDepthWithReservedStack()V [1]
Depth: 59544
其输出结果非常不稳定。我猜想这里还有其他机制在工作,而这里我只做了简单演示。