java 板


LINE

直接用個範例來說明: 這個Method純粹只是為了當範例用的 當傳進去的x不等於y的時候,他會把x+1,然後繼續遞迴下去 直到x==y為止 int methodt (double x , double y) { if (x==y) return x; else return Methodt(x+1,y); } 假設,現在x = 1, y = 3 執行 methodt(1,3); 那程式會這樣跑: 1. methodt(1,3); <= 呼叫method,建立一個methodt的「域」 2. int methodt (double x , double y) <= 宣告了 x 跟 y 兩個變數 { 也就是說,記憶體中多這兩個值 if (x==y) return x; 一般的IDE都會附檢視變數的功能 else return Methodt(x+1,y); 請把他找出來,看看記憶體中有 } 哪些變數 3. int methodt (double x , double y) { if (x==y) return x; <= 比較 x==y ,這應該不用解釋 else return Methodt(x+1,y); } 3. int methodt (double x , double y) { if (x==y) return x; else return Methodt(x+1,y); <= 把 x+1,再次呼叫Methodt } 再次宣告一個域 4. int methodt (double x , double y) <= 再次宣告 xy 兩個變數 { 並令 x = x+1y = y if (x==y) return x; 現在記憶體中有methodt methodt兩個域 else return Methodt(x+1,y); x=1 y=3 x=2 y=3 四個變數 } 5. int methodt (double x , double y) { if (x==y) return x; else return Methodt(x+1,y); <= 再次宣告一個域 } 6. int methodt (double x , double y) { if (x==y) return x; <= 到這一步時,記憶體中有3個域 else return Methodt(x+1,y); 6個變數 } 7. int methodt (double x , double y) { if (x==y) return x; <= 因為條件成立,所以返回 x else return Methodt(x+1,y); } 8. int methodt (double x , double y) { if (x==y) return x; else return Methodt(x+1,y); } <= 返回值後,釋放 x y 兩個變數 並刪除域,留給JVM做GC 9. int methodt (double x , double y) { if (x==y) return x; else return Methodt(x+1,y); <= 返回 3 ,以下同上 } //================================================================= 以上是遞迴的基本步驟 可以看的到,呼叫一次Methodt就會建立一個域,並在記憶體中佔了兩個變數 有些程式的寫法可能會出問題 例如說... Methodt(4,3); 這樣的話,程式會無止盡的遞迴下去,直到記憶體用光 跳出StackOverflowError 遇到StackOverflowError,絕大多數都是這一種狀況 另一種 是無意義的「巨大」變數 例如: void Methodt (byte[] a) { //DoSomeThing byte b = new byte[a.length]; System.arraycopy(a, 0, b, 0, a.length); <= 拷貝陣列 Methodt(b); } 萬一那個 a 是一張5MB的圖片的話 遞迴一層就會吃掉5MB 通常跑不了幾層就會 StackOverflowError ※感謝sbrhsieh大大指正 這種狀況出現的會是 OutOfMemoryError ,而不是StackOverflowError 因為byte[]是配置在heap中,而不是stack中 ※ 引述《tossakite (昱)》之銘言: : 不好意思我是java的新手(剛學第五天...) : 如果發問不得當真的很抱歉... : 我目前正在寫小畫家 : 但剛剛寫油漆桶功能的時候卻遇到奇怪的問題 : 基本上我是用Depth First Search的概念寫成遞迴函數 : 從滑鼠點下去的那點作為樹根 一直向外擴散尋找需要變色的像素 : 擴散順序是先往右邊找 再往上、往左 最後往下找 : 結果測試結果發現 : 如果用鉛筆圈出一塊小面積(有測過奇形怪狀) 油漆桶都可以成功把內部著色 : 但如果面積稍微大一點(大概超過50x50個像素的話) : 它就無法著色了 : 所以懷疑是如果遞迴呼叫太多次它就會發生問題 : 測試了一下也發現 : 如果面積太大的話 遞迴總是跑到一半就自動被強行結束(每次結束的點都不一樣) : 可是遞迴次數應該不可能會有限制吧!? : 上網都沒有查到這方面有什麼限制存在 : 也不太可能是演算法出錯 因為面積夠小還是可以成功著色 : 由於程式碼有點多(大概25行) 不太確定要不要PO出來 : 遞迴函數傳入的參數有三個 : 一個是BufferedImage : 一個是跟像素數量一樣多的布林二維陣列 還有一個Point : 難道是傳入的參數太龐大的問題? : 如果有需要檢查程式碼的話我可以再貼出來@@ : 煩請高手解惑!! : ---------------------------- : 對不起我不知道有錯誤訊息這種東西QQQQ : 是下面這個嗎? : Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError : 它後面接了很多 at ..... : 前幾個是這樣 : at java.awt.image.DirectColorModel.getRGB(DirectColorModel.java:438) : at java.awt.image.DirectColorModel.getRGB(DirectColorModel.java:704) : at java.awt.image.BufferedImage.getRGB(BufferedImage.java:871) : at painter.test2.recursive(test2.java:887) : at painter.test2.recursive(test2.java:891) : at painter.test2.recursive(test2.java:891) : 之後全部都是recursive函數 : 對不起我以後會注意版規的QQ -- --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 125.233.156.129
1F:推 tossakite:原來如此!!! 很感謝你的詳細說明~:D 03/01 23:57
2F:→ tossakite:看來只好放棄美麗的遞迴了QQ 用迴圈寫DFS感覺好難.... 03/01 23:59
3F:→ LaPass:其實我覺得你想辦法把幾個比較「笨重」的參數移到外面,應 03/02 00:50
4F:→ LaPass:該就可以解決問題了.... 03/02 00:51
5F:推 tossakite:我努力把參數縮到剩一個Point物件 還是畫不了大面積... 03/02 01:41
6F:推 tossakite:我把它寫成完全不用傳參數 函數裡也沒有宣告任何新東西 03/02 02:06
7F:→ tossakite:竟然還是StackOverFlow...!! 請問所謂的域很耗資源嗎? 03/02 02:09
8F:推 eieio:你 50x50 的區域,寫 recursive 的話就有可能有 250 層 03/02 02:28
9F:→ LaPass:之前除這種錯時,跑到一萬層都沒問題.... 03/02 09:07
試著加這一段下去看看 static int num = 0; int Methodt() { num++; //輸出 num ,如果太多層的話,可以用 if(num%100==0)去減少輸出 int re = Methodt(); num--; return re; } 這樣就可以知道跑到第幾層了 我現在才發現範例的傳回值是錯的.... ※ 編輯: LaPass 來自: 61.59.16.65 (03/02 11:07)
10F:→ gameking:會不會是電腦設備的問題 記憶體太小? 03/02 15:17
11F:推 tossakite:蛤真的嗎? 可是4G應該還算OK吧@@ 03/02 23:36
12F:推 tossakite:它最高可以畫到6000左右個像素 但很奇妙的是 超過6000 03/02 23:50
13F:→ tossakite:個像素的話 它幾乎遞迴跑4000多次就停了(但偶爾會8000多 03/02 23:53
14F:→ tossakite:阿應該要計算層才對= = 等一下我重寫... 03/02 23:58
15F:→ tossakite:結果是 極限是在2068~2074層之間很規律的週期變化... 03/03 00:04







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:iOS站內搜尋

TOP