[問題] 簡單的程式就有 memory leak 了

看板MacDev作者 (吹笛牧童)時間10年前 (2014/04/12 06:05), 10年前編輯推噓3(3021)
留言24則, 9人參與, 最新討論串1/4 (看更多)
連續天天加班到凌晨,總算專案快出一版了 是中點,不是終點 最近試著用 instrument 去抓 memory leak,卻發現記憶體吃得離譜 不得已又寫了個小程式,離開公司架構,小小的測試一下 寫得很簡單,就兩個畫面切來切去 1.開一個新程式 2.在 storyboard 上,擺一個 button 3.開一個新的 xib & UIViewController 4.新 xib 上也擺一個 button 5.coding 第一個 button,很簡單的載入 xib 檔,開始 MyViewController 而已 MyViewController* controller = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; [self presentViewController:controller animated:true completion:nil]; 第二個 button,很簡單的關閉 MyViewController, 回到原來的 controller [self dismissViewControllerAnimated:true completion:nil]; 程式夠簡單了,抄書的 然後在兩個檔 ( storyboard & xib ) 上,擺一大堆 button 這麼做只是為了增加記憶體消耗,使結果明顯 執行,快速的按 button1 , button2, 讓畫面切來切去 就這樣竟然也有 memory leak (不要只用 Xcode 的環境看,要打開 instrument 看,才明顯) 程式顯示, [self presentViewController:controller animated:true completion:nil]; 光這行都會吃記憶體 我可以理解的是,當我把 controller 傳入 present view 函式,它就被保留了 難道我必需自己把它移出刪除嗎? 這樣太不合理了!! 寫一個 -(void)delloc 來驗證,也會發覺在按下 close button 時有 delloc 啊 那記憶體佔用又是為什麼呢? -- 活動/美食計劃 蘭嶼 魚白 勝興車站 星月天空 武陵 草嶺古道 嘉義阿里山小火車 保齡球  司馬庫斯 手包水餃 日月潭纜車 合歡攻頂 馬祖 鹽山 南庄 澎湖 溪頭/松林町 南投天梯 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 60.251.197.63 ※ 文章網址: http://www.ptt.cc/bbs/MacDev/M.1397253951.A.737.html

04/12 06:06, , 1F
又天亮了,唉
04/12 06:06, 1F

04/12 07:31, , 2F
有dealloc不代表物件有正確的Release
04/12 07:31, 2F
這個知道 但這麼簡單的 sample,又是抄書的 這樣也不行 總不能叫我把 storyboard & xib 中, 所有的物件用 for loop 一個個 remove from super view 吧! ;; 聽主管在'猜'(沒經驗,也只能大猜特猜了) 那些記憶體是暫時沒釋放,等空間不足時就會被整理釋出 這是什麼思維?這不就是 GC 嗎? 所謂用一個 thread 去繞行所有物件,找到沒被 reference 的就自動刪除 thread 不一定何時做這件事;ARC 不是這樣吧!! 以 ARC 是 compiler 自動插入 retain & release 來說 我以為記憶體的釋放會是即時的 ※ 編輯: HuangJC (60.251.197.63), 04/12/2014 08:40:34

04/12 09:34, , 3F
要嘛去聘一個會的人不然就用別的吧, 都給你們猜就飽了啊
04/12 09:34, 3F
這... 我是兵,我不用扛這責任 主管可要挨罵了:養你做什麼吃的 不過事實上是那人請來,我就可以走路了 XDDDD 我們還是有些鬼才啦,從不懂到懂,到弄出東西...

04/12 11:36, , 4F
我在上面各擺了兩百多個button 怎沒leak ?
04/12 11:36, 4F
我下週上班時把自己程式壓縮一下,可以給大家下載;這樣最沒爭議 然後測試步驟... 這很難表達,但那麼簡單應該沒問題 再來就是抓幾個畫面吧.. 有畫面才有真相啊.. ※ 編輯: HuangJC (175.180.126.61), 04/12/2014 14:35:02

04/12 23:34, , 5F
在dealloc裡用 CFGetRetainCount() 抓一下每個object的
04/12 23:34, 5F

04/12 23:35, , 6F
reference count, ARC也不是萬能,有些情況要人腦分析.
04/12 23:35, 6F

04/13 20:10, , 7F
ARC是即時釋放沒錯 沒釋放就是有地方沒寫好
04/13 20:10, 7F

04/14 02:23, , 8F
真的很感謝你們;雖然不知多久後又要害你們失望
04/14 02:23, 8F

04/14 02:24, , 9F
可是陌生人能如此給機會諒解對方,你們都很了不起..
04/14 02:24, 9F

04/15 12:35, , 10F
印象中上課的老師有提過,iOS就是記憶體滿了才清除,機制也很
04/15 12:35, 10F

04/15 12:36, , 11F
像你所描述的方式
04/15 12:36, 11F

04/15 12:37, , 12F
原本的記憶體管理 release本來也是操作retain而已呀
04/15 12:37, 12F

04/15 16:26, , 13F
04/15 16:26, 13F

04/15 17:09, , 14F
http://tinyurl.com/la87dej 執行結果,可以看到記憶體
04/15 17:09, 14F

04/15 17:09, , 15F
愈吃愈多
04/15 17:09, 15F

04/15 20:51, , 16F
你需要開放權限出來,我用我的mail請求權限了,
04/15 20:51, 16F

04/15 20:51, , 17F
開頭是pippi的就是我的mail
04/15 20:51, 17F

04/15 21:40, , 18F
有看到;不懂的是我以為我給的網址就是公開權限了
04/15 21:40, 18F

04/15 21:40, , 19F
那程式不就也無法下載?
04/15 21:40, 19F

04/15 23:09, , 20F
1. 根本沒有leak
04/15 23:09, 20F

04/15 23:10, , 21F
2. allocation表示的是現在在用的Memory,只要程式在跑
04/15 23:10, 21F

04/15 23:10, , 22F
就會有記憶體使用.
04/15 23:10, 22F

04/15 23:10, , 23F
3. Leak是看下面的leak欄位有沒有出現紅線.
04/15 23:10, 23F
謝謝,拖了一天;週一忙,週二想吐 Orz 1. 說沒有 leak 我懂;這是我長期以來的筆誤 試考量這樣的狀況 @interface MyController @property id View; @end @interface MyView @property id Controller; @end 也就是說, 元件 A 內部有指標指向元件 B 然後元件 B 內部又有指標指回元件 A 因為元件 B 的緣故,所以元件 A 的 ref count 不會歸 0 造成無法自動釋放; 這問題可用 weak 指標解決 而沒解決之前,記憶體佔用不會解決;這不叫 leak, 不過我不知這該叫什麼 我擔心的是這種 2. 以 C/C++ 來說,因為沒有 arc, 我自己控制 我還算可以理解 leak 是怎麼產生的 BYTE* p = new BYTE[10]; // delete[] p; p = null; 這樣就好,因為我沒先釋放 p 就把指標歸0了, 這樣誰還能存取那塊空間? 沒有.. 沒有就是 leak 了 但在 ARC 控制之下, 在這裏, p = nil 就足以指示一個釋放指令 所以我反而想請教: 怎麼寫一個最短的 leak demo 因為我以為, 如果我可以把 ref count 歸 0,那 arc 都會幫我釋放 3. "只要程式在跑,就會有記憶體使用" 可是我的狀況是不斷的按按鍵,讓畫面在兩個畫面間跳 (雖然這裏不是用 push/pop 來寫, 而是用 present/dismiss) 所以當我跳回原畫面時, 記憶體佔用不該恢復原貌嗎? 這樣愈吃愈多是正常的? (我的畫面就是一直按而產生的,按愈多下記憶體佔用愈多) 謝謝 ※ 編輯: HuangJC (175.180.126.61), 04/16/2014 03:38:11

04/22 23:31, , 24F
Please implement unwinding storyboard segue
04/22 23:31, 24F
文章代碼(AID): #1JI6S_St (MacDev)
文章代碼(AID): #1JI6S_St (MacDev)