java遞歸棧溢出解決方法 遞歸調(diào)用造成堆棧溢出,該如何解決?
遞歸調(diào)用造成堆棧溢出,該如何解決?溢出的意思就是越界,操作系統(tǒng)會給每個進(jìn)程分配一個最大上限的堆??臻g,如果超過了這個內(nèi)存空間大小程序就會coredump,就像你使用int *pi = new int[
遞歸調(diào)用造成堆棧溢出,該如何解決?
溢出的意思就是越界,操作系統(tǒng)會給每個進(jìn)程分配一個最大上限的堆??臻g,如果超過了這個內(nèi)存空間大小程序就會coredump,就像你使用int *pi = new int[100000000]會崩潰一樣,因為這里堆溢出了。
操作系統(tǒng)分配給一個進(jìn)程的??臻g是2M,堆空間在32位機(jī)器上是4G。如果你的進(jìn)程的棧空間使用超過了2M就會棧溢出,堆使用超過4G就會堆溢出。
那么遞歸為什么會導(dǎo)致棧溢出呢?相信樓主知道棧的出入規(guī)則,先入后出,遞歸的話那么先入的一致不能出棧,會一致存在??臻g中,這樣就容易導(dǎo)致棧滿而溢出。
哈哈,還有不懂不?
java遞歸改為循環(huán)后為什么不會導(dǎo)致棧內(nèi)存溢出?
我們知道,在編程中如果想讓某個業(yè)務(wù)重復(fù)執(zhí)行,一般有兩種實現(xiàn)方式,分別是:遞歸和循環(huán)。在實際編碼過程中,我們并不建議使用遞歸,反而是建議使用循環(huán),這是為什么呢?
遞歸不當(dāng)會導(dǎo)致內(nèi)存溢出
其實不單單是Java,任何一款編程語言,如果遞歸寫法不對,那就可能導(dǎo)致內(nèi)存溢出!
學(xué)過Java的朋友肯定或多或少都聽說和了解過棧內(nèi)存和堆內(nèi)存,程序在運行時,電腦操作系統(tǒng)會給每個進(jìn)程都分配有堆內(nèi)存、棧內(nèi)存,所分配的堆棧內(nèi)存都是有上限的,一旦超過了這個上限就會導(dǎo)致內(nèi)存溢出現(xiàn)象。
為什么遞歸操作容易導(dǎo)致內(nèi)存溢出呢?原因主要有以下幾點:
遞歸方法體內(nèi),如果終止遞歸的條件寫錯了,那可能會導(dǎo)致無限遞歸,最終導(dǎo)致內(nèi)存溢出;
即使遞歸方法及退出遞歸條件都是正常的,但若遞歸深度過深(遞歸次數(shù)過多),也會導(dǎo)致棧內(nèi)存溢出!因為棧的出入規(guī)則是先入后出(先入棧的最后再出來),如果遞歸次數(shù)過多就會導(dǎo)致只入棧不出棧,最終棧內(nèi)存溢出。
遞歸改循環(huán)可以降低內(nèi)存溢出的可能
注意,遞歸寫法改成循環(huán)寫法可以降低內(nèi)存溢出的風(fēng)險,但這不是絕對的,如果循環(huán)寫成了死循環(huán)一樣會導(dǎo)致內(nèi)存溢出。
遞歸寫法改成循環(huán)寫法的好處是,不會在短時間內(nèi)出現(xiàn)棧的只入不出現(xiàn)象,所以可以規(guī)避棧內(nèi)存溢出現(xiàn)象。
如何避免遞歸函數(shù)堆棧溢出?
雖然我沒有親眼見到你的源程序代碼,但是根據(jù)你所描述的情況來看,我估計你在你的程序源代碼中使用了遞歸調(diào)用子函數(shù)。因為程序在頻繁地遞歸調(diào)用子函數(shù)過程中就會產(chǎn)生頻繁地產(chǎn)生壓棧、出棧操作。
遞歸調(diào)用子函數(shù)的最大優(yōu)點就是:程序的編寫起來較容易、并且程序的可讀性較好;但是它也有它的缺點。即:如果需要處理的數(shù)據(jù)量很大時,就必然會導(dǎo)致堆棧溢出的現(xiàn)象。此時就必須將遞歸算法修改為非遞歸的算法。
至于具體的修改方法,現(xiàn)在的數(shù)據(jù)結(jié)構(gòu)教材上都有講解的。但是這樣一改,其程序的非遞歸可讀性必然不如遞歸調(diào)用的看起來可讀性要好。
例如:最最經(jīng)典的遞歸調(diào)用子函數(shù)就是:計算一個整數(shù)的階乘。當(dāng)需要計算的整數(shù)比較小的時候,那么使用遞歸調(diào)用子函數(shù)來編寫程序,那簡直就是一種享受。但是當(dāng)需要計算的整數(shù)很大、很大的時候,那么如果還是使用遞歸算法,必然會造成堆棧的溢出。此時就必須要把遞歸算法修改為非遞歸算法。
Pythpn如何解決遞歸太深導(dǎo)致棧溢出的問題呢?
最簡單的解決方案,也是最愚蠢的解決方案,寫多個對象或者方法函數(shù),分層解決。
例如:0-100 使用A;101-200 使用B。 交替解決,這可比你設(shè)置 sys.setrecursionlimit(99999999)。
我是python新手,不對勿噴。