This is clearly JVM- and possibly also architecture-specific.
I've measured the following:
static int i = 0;
public static void rec0() {
i++;
rec0();
}
public static void main(String[] args) {
...
try {
i = 0; rec0();
} catch (StackOverflowError e) {
System.out.println(i);
}
...
}
using
Java(TM) SE Runtime Environment (build 1.7.0_09-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mixed mode)
running on x86.
With a 20MB Java stack (-Xss20m
), the amortized cost fluctuated around 16-17 bytes per call. The lowest I've seen was 16.15 bytes/frame. I therefore conclude that the cost is 16 bytes and the rest is other (fixed) overhead.
A function that takes a single int
has basically the same cost, 16 bytes/frame.
Interestingly, a function that takes ten ints
requires 32 bytes/frame. I am not sure why the cost is so low.
The above results apply after the code's been JIT compiled. Prior to compilation the per-frame cost is much, much higher. I haven't yet figured out a way to estimate it reliably. However, this does mean that you have no hope of reliably predicting maximum recursion depth until you can reliably predict whether the recursive function has been JIT compiled.
All of this was tested with a ulimit
stack sizes of 128K and 8MB. The results were the same in both cases.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…