I am asking a question about "java stack overflow" in the "stackoverflow" site :)
A particular thread which makes some recursive function calls for a particular input runs fine in Oracle Java 7 (64 bit) for a configured stack size of 228k (-Xss228k).
However, the same thread running the same recursive code for the same input throws a java.lang.StackOverflowError in Oracle Java 8 (64 bit) for the same stack size of 228k. It runs fine in Java 8 if the stack size is increased to 512k (-Xss512k).
Any idea why this could happen? Have any changes been made in Java 8 (Hotspot JVM) compared to Java 7 which could increase the stack memory consumption for recursive function calls? I can provide additional details if required.
(Edit) NOTE: The same recursion depth works "always" in Java 7 but fails "always" in Java 8 for a stack size of 228k.
I wrote a small test for different recursion scenarios (static or instance method, different number of int parameters). Here's the results (number of calls before StackOverflowError
occurs) on different versions of HotSpot JVM 64bit with -Xss228k
option. Note that numbers differ somewhat between runs (I launched twice with every JVM):
St/0 St/1 St/2 St/3 St/4 In/0 In/1 In/2 In/3 In/4
1.7.0_60 2720 2519 2309 2131 1979 2519 2309 2131 1979 1847
1.7.0_60 2716 2516 2306 2128 1976 2516 2306 2128 1976 1845
1.7.0_79 2716 2516 2306 2128 1976 2516 2306 2128 1976 1845
1.7.0_79 2729 2528 2317 2139 1986 2528 2317 2139 1986 1853
1.7.0_80 2718 2518 2308 2130 1978 2518 2308 2130 1978 1846
1.7.0_80 2738 2536 2324 2146 1992 2536 2324 2146 1992 1859
____________________________________________________________________
1.8.0_25 2818 2469 2263 2089 1940 2469 2263 2089 1940 1810
1.8.0_25 3279 2468 2262 2088 1939 2468 2262 2088 1939 1810
1.8.0_40 2714 2467 2262 2088 1938 2467 2262 2088 1938 1809
1.8.0_40 2735 2486 2279 2104 1953 2486 2279 2104 1953 1823
1.8.0_60 2729 2481 2274 2099 1949 2481 2274 2099 1949 1819
1.8.0_60 2719 2472 2266 2091 1942 2472 2266 2091 1942 1812
____________________________________________________________________
1.9_b80 2717 2470 2264 2090 1941 2470 2264 2090 1941 1811
1.9_b80 2715 2468 2263 2088 1939 2468 2263 2088 1939 1810
It's quite expected that Instance/0
is the same as Static/1
and so on as instance call need to pass this
as an additional argument.
So indeed there's some degradation of number of recursive calls allowed (except for Static/0
case) betwee JDK 7 and JDK 8: you lose around 30-40 calls (roughly 5%) of total count. So probably in your application you was very close to the limit. By the way I noticed a sudden jump between -Xss256k
and -Xss260k
(tested on 1.8.0_40):
St/0 St/1 St/2 St/3 St/4 In/0 In/1 In/2 In/3 In/4
-Xss256k 2724 2476 2270 2095 1945 2476 2270 2095 1945 1816
-Xss260k 4493 3228 2959 2731 2536 3228 2959 2731 2536 2367
So you may try to increase stack size to -Xss260k
and it should be enough for your task.
By the way 32-bit JVM allows much more calls with the same -Xss228k
:
St/0 St/1 St/2 St/3 St/4 In/0 In/1 In/2 In/3 In/4
7u67_32b 7088 5078 4655 4297 3990 5078 4655 4297 3990 3724
7u67_32b 6837 5092 4667 4308 4001 5092 4667 4308 4001 3734
Thus it's also possible that you've switched from 32-bit Java-7 to 64-bit Java-8. In this case, of course much more stack space is needed as even with compressed OOPs pointers in the stack seem to be 64bit, thus occupying more space.