iOS开发:移除所有子视图后内存未恢复至初始值的原因
嘿,这个问题我之前做批量视图性能测试的时候也碰到过!其实这背后是几个iOS内存管理和系统机制的细节在起作用,我给你拆解清楚:
ARC销毁对象≠内存立刻还给系统
咱们用的ARC会在对象引用计数归0时立刻调用dealloc销毁对象,但这只是把内存标记为「当前App可以复用的空闲内存」,并不会马上把内存页还给操作系统。你在模拟器里看到的91M是App进程当前占用的总内存,其中一部分是已经释放但系统还没回收的空闲块。等后续你的App需要新内存时,会优先复用这部分空闲内存,不会立刻向系统申请新的。UITableView的内部缓存残留
UITableView本身自带cell复用缓存池,哪怕你没给它设置dataSource,它初始化时也可能预创建了一些缓存用的cell对象。当你把tableView从父视图移除后,tableView的引用计数会降为0,但它缓存池里的cell销毁可能要等下一个RunLoop周期才能完成——所以你刚移除子视图就查看内存,会看到这部分临时残留。模拟器内存统计的「滞后性」
模拟器的内存统计并不是实时精准的,它展示的是进程的虚拟内存占用,包含了系统为App预分配的内存块、Core Animation的图层渲染缓存这些临时数据。你可以试试触发一次内存警告(模拟器菜单Hardware > Simulate Memory Warning),之后再看内存,大概率会降到更接近53M的水平。排查是否有隐性循环引用
虽然可能性不大,但如果你的代码里不小心出现了循环引用(比如自定义cell强引用了UITableView,或者tableView的关联对象强引用回它),会导致部分tableView或其附属对象无法被释放。你可以用Xcode的Instruments工具里的Allocations跟踪一下,看看那些UITableView是否真的被调用了dealloc,这比单纯看内存数值更能确认是否有泄漏。
总的来说,这种「内存没完全回落」的情况大多是正常的系统行为,不是内存泄漏。如果你的App后续运行时内存没有持续上涨,就不用太担心啦。
内容的提问来源于stack exchange,提问作者无夜之星辰

