java內(nèi)存溢出排查工具 java遞歸改為循環(huán)后為什么不會(huì)導(dǎo)致棧內(nèi)存溢出?
java遞歸改為循環(huán)后為什么不會(huì)導(dǎo)致棧內(nèi)存溢出?我們知道,在編程中如果想讓某個(gè)業(yè)務(wù)重復(fù)執(zhí)行,一般有兩種實(shí)現(xiàn)方式,分別是:遞歸和循環(huán)。在實(shí)際編碼過(guò)程中,我們并不建議使用遞歸,反而是建議使用循環(huán),這是為什
java遞歸改為循環(huán)后為什么不會(huì)導(dǎo)致棧內(nèi)存溢出?
我們知道,在編程中如果想讓某個(gè)業(yè)務(wù)重復(fù)執(zhí)行,一般有兩種實(shí)現(xiàn)方式,分別是:遞歸和循環(huán)。在實(shí)際編碼過(guò)程中,我們并不建議使用遞歸,反而是建議使用循環(huán),這是為什么呢?
遞歸不當(dāng)會(huì)導(dǎo)致內(nèi)存溢出
其實(shí)不單單是Java,任何一款編程語(yǔ)言,如果遞歸寫(xiě)法不對(duì),那就可能導(dǎo)致內(nèi)存溢出!
學(xué)過(guò)Java的朋友肯定或多或少都聽(tīng)說(shuō)和了解過(guò)棧內(nèi)存和堆內(nèi)存,程序在運(yùn)行時(shí),電腦操作系統(tǒng)會(huì)給每個(gè)進(jìn)程都分配有堆內(nèi)存、棧內(nèi)存,所分配的堆棧內(nèi)存都是有上限的,一旦超過(guò)了這個(gè)上限就會(huì)導(dǎo)致內(nèi)存溢出現(xiàn)象。
為什么遞歸操作容易導(dǎo)致內(nèi)存溢出呢?原因主要有以下幾點(diǎn):
遞歸方法體內(nèi),如果終止遞歸的條件寫(xiě)錯(cuò)了,那可能會(huì)導(dǎo)致無(wú)限遞歸,最終導(dǎo)致內(nèi)存溢出;
即使遞歸方法及退出遞歸條件都是正常的,但若遞歸深度過(guò)深(遞歸次數(shù)過(guò)多),也會(huì)導(dǎo)致棧內(nèi)存溢出!因?yàn)闂5某鋈胍?guī)則是先入后出(先入棧的最后再出來(lái)),如果遞歸次數(shù)過(guò)多就會(huì)導(dǎo)致只入棧不出棧,最終棧內(nèi)存溢出。
遞歸改循環(huán)可以降低內(nèi)存溢出的可能
注意,遞歸寫(xiě)法改成循環(huán)寫(xiě)法可以降低內(nèi)存溢出的風(fēng)險(xiǎn),但這不是絕對(duì)的,如果循環(huán)寫(xiě)成了死循環(huán)一樣會(huì)導(dǎo)致內(nèi)存溢出。
遞歸寫(xiě)法改成循環(huán)寫(xiě)法的好處是,不會(huì)在短時(shí)間內(nèi)出現(xiàn)棧的只入不出現(xiàn)象,所以可以規(guī)避棧內(nèi)存溢出現(xiàn)象。
java棧內(nèi)存溢出怎么產(chǎn)生?
1.如果線程請(qǐng)求分配的棧容量超過(guò)java虛擬機(jī)棧允許的最大容量的時(shí)候,java虛擬機(jī)將拋出一個(gè)StackOverFlowError異常。2.如果java虛擬機(jī)棧可以動(dòng)態(tài)拓展,并且擴(kuò)展的動(dòng)作已經(jīng)嘗試過(guò),但是目前無(wú)法申請(qǐng)到足夠的內(nèi)存去完成拓展,或者在建立新線程的時(shí)候沒(méi)有足夠的內(nèi)存去創(chuàng)建對(duì)應(yīng)的虛擬機(jī)棧,那java虛擬機(jī)將會(huì)拋出一個(gè)OutOfMemoryError異常。剛看到題主在問(wèn)題下的評(píng)論,xss分配的應(yīng)該是每個(gè)線程的棧大小,線程數(shù)量和整個(gè)進(jìn)程的大小是由操作系統(tǒng)來(lái)限制的。對(duì)于單個(gè)線程,棧內(nèi)存容量減小,或者變量表深度增大,就會(huì)造成StackOverFlow,這點(diǎn)我跟題主想的一樣。至于是堆內(nèi)存溢出還是方法區(qū)內(nèi)存溢出還是棧內(nèi)存溢出,其實(shí)可以用一些工具比如JConsole來(lái)監(jiān)視。
java棧內(nèi)存溢出怎么產(chǎn)生?
棧溢出有兩種,一種是stackoverflow,另一種是outofmemory,前者一般是因?yàn)榉椒ㄟf歸沒(méi)終止條件,后者一般是方法中線程啟動(dòng)過(guò)多。
jvm的內(nèi)存模型?怎么棧溢出,堆溢出?gc?真的用到過(guò)沒(méi)?
但是在平常編程中,肯定經(jīng)常遇到OOM問(wèn)題。jvm的內(nèi)存模型,簡(jiǎn)單來(lái)說(shuō)就是堆棧結(jié)構(gòu),實(shí)際上內(nèi)存的劃分很復(fù)雜。推薦《深入java虛擬機(jī)》來(lái)入門了解。棧溢出和堆溢出,顧名思義,就是棧和堆上的內(nèi)存不夠用了,就拋出OOM異常唄??梢酝ㄟ^(guò)調(diào)整參數(shù)來(lái)控制堆棧的內(nèi)存大?。?Xmn -XmxGC就是針對(duì)堆,棧,方法區(qū)的垃圾回收行為。這些問(wèn)題還是要看書(shū)的,打字打死也說(shuō)不完。