函数的最大堆栈空间

3

我正在尝试确定我的分支/合并实现何时会出现堆栈溢出。

我知道编译器在编译时确定函数所需的最大堆栈空间。因此,这些信息应该在我的Java代码的.class文件中可用。但是,我似乎无法找到如何获取这个值。

我能否在运行时打印它,或者有人可以指向我在类文件中可能找到它的地方吗?在gedit中,所有内容都是无意义的,因此我无法找到它。


2
.class文件并不是用来供人阅读的,它是机器码。不要费心在里面翻找了。此外,这里有一些可能对您有帮助的信息:https://dev59.com/7WIj5IYBdhLWcg3wpmoH#20030999 - Dioxin
如果你真的想查看 .class 文件,使用 javap 来给你反汇编。 - vandale
另一个支持你的问题的资源(无法编辑上一个评论):http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#threads_oom - Dioxin
2个回答

3

没有简单的方法可以判断方法调用是否会导致堆栈溢出。

虽然您可以确定方法在堆栈上需要的槽位数量,但这并不能告诉您实际所需的字节数。

Java字节码使用实际堆栈的抽象表示,其中堆栈被视为由抽象的“槽位”组成。this引用、方法参数和局部变量都占用堆栈上的一个或两个槽位(long和double需要两个槽位,其他所有内容均计为一个槽位)。这是您可以从类文件中获取的信息。

仍然缺少的是如何将槽位实际转换为堆栈内存,以及JIT实际从字节码创建的内容。JIT也可能决定在执行优化(例如代码不变移动)时添加临时变量。

另外,当您调用本机方法时,无法确定调用将使用多少堆栈内存。

您看,很多情况取决于当前的JRE、VM和平台。再加上缺乏一个简单的内置方法来确定实际堆栈的大小,这使得确定需要多少堆栈和可用多少堆栈变得不切实际。


我应该同意你的看法。我尝试过JBE工具,但它没有给我硬性数据。我想我会用更一般的方式来表达我的答案。谢谢你提供的信息。也许你可以提供一个更详细信息的链接吗?我想要深入了解! :) - Christophe De Troyer
1
@ChristopheDeTroyer 所有肮脏的细节最终都在http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html Java虚拟机规范中描述。特别感兴趣的可能是第4章(类文件格式,特别是4.7.3)和字节码指令集(第6章)。可能有更简单(精简)的第三方文章在网上回答特定问题。 - Durandal

2

JBE 是一款很好的独立工具,可以让您浏览(和编辑)类文件。它显示的一个信息是某个方法的最大堆栈深度。如果 JBE 可以访问此信息,则如果您打算使用字节码解析库,则可能可以实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接