2011-12-14 103 views
4

在递归调用期间,在Java中获取或计算可用剩余堆栈内存的最佳方法是什么?在Java中获得剩余堆栈内存的最佳方式?

(我试图段深刻的递归调用使用尽可能多的堆栈越好(对于速度性能的缘故),但没有击中堆栈溢出。

我已经做了“堆“版本,其中进行了速度性能开销,这就是为什么我在做这种优化。)

回答

1

没有办法以便携的方式做到这一点。

这不仅是OS特定的,在实践中,堆栈的最大尺寸是受多个约束(ulimit -c,可用虚拟内存量,-Xss-XX:ThreadStackSize设置等)。这使得很难知道哪个约束将首先被命中,即使您可以可靠地测量到目前为止已经消耗了多少堆栈空间。

+1

好吧,我不介意将这些值中的最低值放在安全的一边。 Xss值不能100%依赖?你是否使用了java.lang.management包,并且可以证明它中没有任何内容允许计算当前的堆栈使用情况和/或剩余的堆栈空间? – Navigateur 2011-12-14 14:18:55

1

你需要什么?好奇而已?什么是度量单位 - 递归调用的字节数或数量?

您随时可以无限递归调用,抓StackOverflowError和计数堆栈帧

+0

不,我试图分割一个深层递归调用尽可能多地使用堆栈,但没有触发堆栈溢出。虽然剩余的递归调用的数量会更好,但字节会很好!如果它不是立即可用,我不介意计算它。 – Navigateur 2011-12-14 13:40:46

1

嗯。如果你担心,你可以随时保留一个深度计数器作为递归的一部分。

+0

不幸的是,递归调用的输入并不总是相同的,所以一个计数器不会让我估计在遇到堆栈溢出之前可以做多少次调用。 – Navigateur 2011-12-14 14:03:06

+0

@Navigateur您能否详细说明“递归调用的输入不总是相同的”?由于提前知道局部变量的数量,你怎么会不知道? – Pacerier 2012-01-29 14:40:34

+0

它接受Object作为输入,并通过反射来遍历它,所以它可以是任何类型,因此可以是任何大小或深度。 – Navigateur 2012-02-02 18:24:27

1

我会写这个方法,以减少递归。通常有办法减少(或不加)递归调用。

如果递归地对列表进行求和,则将第一个值添加到其余的总和中,这将调用深度为N.但是,如果将列表中的值减半并且求和值。 (如果列表中只有一个,则返回值)递归深度为log2(N)。

1

我很惊讶迭代方法的性能较差。通常,由于方法调用的开销,递归方法会更慢。如果您的算法可以作为尾递归实现,那么迭代实现几乎肯定会更快。你能告诉我们更多关于你实际想做什么的吗?也许在性能上的差异是更多的算法,而不仅仅是递归递归迭代。下面是一些CS lecture notes的例子,它们引用计算斐波那契数的递归方法,即O(2^n),而迭代方法是O(n)。我相信(尽管我还没有尝试过),可以编写一个递归的O(n)的斐波那契数生成器。

编辑:

最后一个想法。恕我直言,使用一种没有堆栈溢出问题的较慢方法要好得多,而不是引入试图确定你要溢出堆栈并具有一些回退机制来避免它的所有复杂性。

相关问题