作者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/cn.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