我问一个关于“堆栈溢出”站点中的"java堆栈溢出“的问题:)
在Oracle 7 (64位)中,对特定输入进行一些递归函数调用的特定线程在配置的堆栈大小为228 K (-Xss228k)时运行良好。
但是,对于相同输入运行相同递归代码的同一个线程在相同堆栈大小的java.lang.StackOverflowError Oracle 8 (64位)中抛出一个。如果堆栈大小增加到512 k (-Xss512k),它在Java8中运行良好。
知道为什么会发生这种事吗?与Java 7相比,Java 8 (Hotspot JVM)中是否有任何更改,这会增加递归函数调用的堆栈内存消耗?如有需要,我可以提供更多细节。
(编辑)注意到:相同的递归深度在Java 7中“总是”工作,但在Java 8中失败“始终”,堆栈大小为228 K。
发布于 2015-09-11 12:22:29
我为不同的递归场景(静态或实例方法,不同数目的int参数)编写了小小的考验。下面是使用StackOverflowError选项的不同版本的HotSpot JVM 64位的结果(发生-Xss228k之前的调用次数)。请注意,不同的运行程序之间的数字有所不同(我在每个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很有可能Instance/0和Static/1是一样的,例如实例调用需要传递this作为附加参数。
因此,在JDK 7和JDK 8之间允许的递归调用数量(除了Static/0情况之外)确实有一些下降:您丢失了总数的30-40个调用(大约5%)。因此,在您的应用程序中,您可能非常接近极限。顺便说一下,我注意到-Xss256k和-Xss260k (在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因此,您可以尝试将堆栈大小增加到-Xss260k,这对您的任务应该足够了。
顺便说一句,32位JVM允许使用同一个-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因此,您也有可能从32位Java-7切换到64位Java-8。在这种情况下,当然需要更多的堆栈空间,因为即使在堆栈中使用压缩的OOPs指针也需要64位,从而占用了更多的空间。
https://stackoverflow.com/questions/32521271
复制相似问题