2011-12-14 98 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)的斐波那契數生成器。

編輯:

最後一個想法。恕我直言,使用一種沒有堆棧溢出問題的較慢方法要好得多,而不是引入試圖確定你要溢出堆棧並具有一些回退機制來避免它的所有複雜性。

相關問題