今天早上我回答了一个关于StackoverflowException的问题。该人员已询问Stackoverflow异常何时发生
请参阅此链接Simplest ways to cause stack overflow in C#, C++ and Java
所以我的问题是,有没有什么方法可以在我们的程序中动态计算方法调用堆栈的大小,然后在调用一个方法之前进行检查,检查方法调用堆栈是否有空间容纳它,以防止StackOverflowException。
由于我是一个java人,我正在寻找java,但也在寻找与没有任何编程语言基础的概念相关的解释。
发布于 2013-05-20 11:54:12
对于32位JVM,JVM可用的总内存约为2-4 4GB,对于64位JVM,总内存约为2-4 4GB的平方(约4-16EB)。JVM将其内存拆分为:
- constructed object and array instances
- static classes and array data (including contained object/array instances)
- thread instances (object instances, runtime data & metadata including thread object monitor lock references)
- aggregate stack memory
- per-thread stack memory **(per-thread allocation controlled via JVM option -Xss)**: method call frames, arguments, return values, locally declared primitives & references to objects
- static constants (primitives)
- String instance pool
- java code: loaded classes and metadata
- JVM internal-use memory (JVM code and data structures)
请参阅http://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryMXBean.html和http://www.yourkit.com/docs/kb/sizes.jsp
有没有什么方法可以用来在我们的程序中动态计算方法调用堆栈的大小
ThreadMxBean.getThreadInfo() & StackOverflow
我建议你不要按照问题中的建议去做,因为:
你不能没有一些复杂的特定于JVM的API来检测/内省动态线程堆栈的内存使用情况-在哪里你会发现这样的API??
StackOverflow异常实际上是你尝试做的最好的response.
一个“正确”的方法应该是指定程序需求,指定所需的运行时环境(包括最小/需要的内存!),并相应地设计您的程序以获得最佳的性能和内存。usage.An反模式是在设计和开发期间不适当地考虑这些事情,而只是想象一些运行时内省魔法可以覆盖这一点。可能存在一些(罕见的!)高性能要求的应用程序,需要在运行时重新安排算法以精确匹配所发现的资源-但这是复杂、丑陋的& expensive.And即使如此,它可能会更好地从"-Xss“参数在宏观级别驱动动态算法更改,而不是从代码中某个位置的确切堆栈内存消耗在微观级别驱动动态算法更改。
发布于 2013-04-26 21:10:53
我希望我猜到你真正想问的是什么。一开始,我以为你是在问你的通话深度是多少。换句话说,基于您当前的方法环境,我认为您想知道触发此异常的可能性有多大。然后我决定你真的很想知道你有多少堆栈深度可以玩。在这种情况下,这里似乎有另一个堆栈溢出问题可以解决这个问题。What is the maximum depth of the java call stack?
这将告诉您如何将其设置为java命令行参数(设置为java,而不是您的程序)。
无论哪种方式,我想指出的是,堆栈溢出主要发生在我进行无休止的递归时。我写了一些方法(当然是错误的),它们会调用自己,并打算在问题解决时停止,但不知何故,终止条件从未达到。这会将方法调用一遍又一遍地放到堆栈上,直到超过最大值为止。这不是我想要的。
我希望这能有所帮助。
发布于 2013-05-20 12:04:28
据我所知,Java中的堆栈限制是相当抽象的,不是用来测量的。事实上,我怀疑堆栈的大小会因机器的不同而不同,这取决于几个因素,比如内存。
除了无限循环/递归,我从来没有得到过抛出堆栈溢出异常的程序。我正在挠头,试图弄清楚如何在没有无限循环的情况下抛出堆栈溢出异常。如果您的程序调用了那么多方法,那么它很可能会同时创建对象,并且您更有可能收到OutOfMemory错误,而不是没有无限循环的堆栈溢出异常。
事实上,堆栈限制会限制你正常工作的能力,这到底是什么意思呢?Java有内存限制,可以应对过度使用资源的情况。堆栈溢出的目的是捕获已经失控并需要捕获的循环/递归。
我想说的是:如果堆栈溢出异常困扰着你的单元测试,你应该检查那些循环/递归函数是否有一些失控的行为。调用堆栈非常、非常长,我怀疑您是否自然地达到了它。
https://stackoverflow.com/questions/16055441
复制相似问题