作者HuangJC (吹笛牧童)
看板MacDev
標題[問題] 簡單的程式就有 memory leak 了
時間Sat Apr 12 06:05:48 2014
連續天天加班到凌晨,總算專案快出一版了
是中點,不是終點
最近試著用 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://webptt.com/m.aspx?n=bbs/MacDev/M.1397253951.A.737.html
1F:→ HuangJC:又天亮了,唉 04/12 06:06
2F:→ darktt:有dealloc不代表物件有正確的Release 04/12 07:31
這個知道
但這麼簡單的 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
3F:→ uranusjr:要嘛去聘一個會的人不然就用別的吧, 都給你們猜就飽了啊 04/12 09:34
這... 我是兵,我不用扛這責任
主管可要挨罵了:養你做什麼吃的
不過事實上是那人請來,我就可以走路了 XDDDD
我們還是有些鬼才啦,從不懂到懂,到弄出東西...
4F:→ yuanruo:我在上面各擺了兩百多個button 怎沒leak ? 04/12 11:36
我下週上班時把自己程式壓縮一下,可以給大家下載;這樣最沒爭議
然後測試步驟... 這很難表達,但那麼簡單應該沒問題
再來就是抓幾個畫面吧..
有畫面才有真相啊..
※ 編輯: HuangJC (175.180.126.61), 04/12/2014 14:35:02
5F:推 abcdefghi:在dealloc裡用 CFGetRetainCount() 抓一下每個object的 04/12 23:34
6F:→ abcdefghi:reference count, ARC也不是萬能,有些情況要人腦分析. 04/12 23:35
7F:推 chchwy:ARC是即時釋放沒錯 沒釋放就是有地方沒寫好 04/13 20:10
8F:→ HuangJC:真的很感謝你們;雖然不知多久後又要害你們失望 04/14 02:23
9F:→ HuangJC:可是陌生人能如此給機會諒解對方,你們都很了不起.. 04/14 02:24
10F:→ Teferi:印象中上課的老師有提過,iOS就是記憶體滿了才清除,機制也很 04/15 12:35
11F:→ Teferi:像你所描述的方式 04/15 12:36
12F:→ Teferi:原本的記憶體管理 release本來也是操作retain而已呀 04/15 12:37
15F:→ HuangJC:愈吃愈多 04/15 17:09
16F:→ darktt:你需要開放權限出來,我用我的mail請求權限了, 04/15 20:51
17F:→ darktt:開頭是pippi的就是我的mail 04/15 20:51
18F:→ HuangJC:有看到;不懂的是我以為我給的網址就是公開權限了 04/15 21:40
19F:→ HuangJC:那程式不就也無法下載? 04/15 21:40
20F:→ atst2:1. 根本沒有leak 04/15 23:09
21F:→ atst2:2. allocation表示的是現在在用的Memory,只要程式在跑 04/15 23:10
22F:→ atst2:就會有記憶體使用. 04/15 23:10
23F:→ atst2:3. Leak是看下面的leak欄位有沒有出現紅線. 04/15 23:10
謝謝,拖了一天;週一忙,週二想吐 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
24F:推 leslielion:Please implement unwinding storyboard segue 04/22 23:31