在递归调用期间,获取或计算Java中可用剩余堆栈内存的最佳方法是什么?
(我正在尝试对一个深度递归调用进行分段以尽可能多地使用堆栈(为了提高速度性能),但不会遇到堆栈溢出。
我已经完成了一个“堆”版本,它带来了速度性能开销,这就是我正在进行优化的原因。)
答案 0 :(得分:1)
无法以便携方式执行此操作。
不仅这是特定于操作系统的,实际上堆栈的最大大小受多个约束(ulimit -c
,可用虚拟内存量,-Xss
和-XX:ThreadStackSize
设置的限制等等)。这使得很难知道哪个约束将首先被击中,即使你可以可靠地测量到目前为止已经消耗了多少堆栈空间。
答案 1 :(得分:1)
你需要什么?好奇而已?什么是度量单位 - 字节或递归调用的数量?
您始终可以进行无限递归调用,捕获StackOverflowError
并计算堆栈帧数
答案 2 :(得分:1)
嗯。如果您担心,您可以随时将深度计数器作为递归的一部分。
答案 3 :(得分:1)
我会将该方法编写为不那么递归。通常有一些方法可以减少(或不减少)递归调用。
如果以递归方式对列表求和,将第一个值添加到其余的总和,则会调用深度为N.但是,如果将列表切成两半并将值相加。 (如果列表中只有一个,则返回值)递归深度为log2(N)。
答案 4 :(得分:1)
我很惊讶迭代方法的性能较差。通常,由于方法调用的开销,递归方法会更慢。如果您的算法可以实现为尾递归,那么作为迭代实现几乎肯定会更快。你能告诉我们更多关于你真正要做的事吗?也许性能上的差异比仅仅为递归迭代迭代更具算法性。以下是一些CS lecture notes的示例,它引用了递归方法来计算Fibonacci数,即O(2 ^ n),而迭代方法是O(n)。我相信(虽然我没有尝试过)可以编写一个递归的Fibonacci数字生成器,它是O(n)。
编辑:
最后一个想法。恕我直言,使用一个没有堆栈溢出问题的较慢方法比引入所有复杂性试图确定你将要溢出堆栈并有一些回退机制来避免它更好。