首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与Java 7相比,运行相同递归代码的同一个线程在Java 8中消耗更多的堆栈内存。

与Java 7相比,运行相同递归代码的同一个线程在Java 8中消耗更多的堆栈内存。
EN

Stack Overflow用户
提问于 2015-09-11 10:28:54
回答 1查看 385关注 0票数 3

我问一个关于“堆栈溢出”站点中的"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。

EN

回答 1

Stack Overflow用户

发布于 2015-09-11 12:22:29

我为不同的递归场景(静态或实例方法,不同数目的int参数)编写了小小的考验。下面是使用StackOverflowError选项的不同版本的HotSpot JVM 64位的结果(发生-Xss228k之前的调用次数)。请注意,不同的运行程序之间的数字有所不同(我在每个JVM中启动了两次):

代码语言:javascript
复制
          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/0Static/1是一样的,例如实例调用需要传递this作为附加参数。

因此,在JDK 7和JDK 8之间允许的递归调用数量(除了Static/0情况之外)确实有一些下降:您丢失了总数的30-40个调用(大约5%)。因此,在您的应用程序中,您可能非常接近极限。顺便说一下,我注意到-Xss256k-Xss260k (在1.8.0_40上进行了测试)之间的突然跳跃:

代码语言:javascript
复制
          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进行更多的调用。

代码语言:javascript
复制
          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位,从而占用了更多的空间。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32521271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档