性能优化01:内存泄漏检测
Leaks
先看看 Leaks
,从苹果的开发者文档里可以看到,一个 app
的内存分三类:
- Leaked memory: Memory unreferenced by your application that cannot be used again or freed (also detectable by using the Leaks instrument).
真正的内存泄漏
:在第一次 pop
的时候报 Memory Leak
,在之后的重复 push
并 pop
同一个 ViewController
过程中,不报 Object Deallocated
,但每次 pop
之后又报 Memory Leak
。这种情况下每回进入并退出一个页面后,就报有新的内存泄漏,同时被报泄漏的对象又从来没有释放过,可以确定是真正的内存泄漏。
Abandoned memory
: Memory still referenced by your application that has no useful purpose.
释放不及时
:在第一次 pop
的时候报 Memory Leak
,在之后的重复 push
并 pop
同一个 ViewController
过程中,对于同一个类不断地报 Object Deallocated
和 Memory Leak
。这种情况属于释放不及时的情况。
Cached memory
: Memory still referenced by your application that might be used again for better performance.
单例
或者被 cache
起来复用:在第一次 pop
的时候报 Memory Leak
,在之后的重复 push
并 pop
同一个 ViewController
过程中,即不报 Object Deallocated
,也不报 Memory Leak
。这种情况下我们可以确定该对象被设计成单例或者 cache
起来了。
总结:
其中Leaked memory
和Abandoned memory
都属于应该释放而没释放的内存
,都是内存泄露,而Leaks
工具只负责检测Leaked memory
,而不管Abandoned memory
。在MRC
时代Leaked memory
很常见,因为很容易忘了调用release
,但在ARC
时代更常见的内存泄露是循环引用
导致的Abandoned memory
,Leaks
工具查不出这类内存泄露,应用有限。
Allocations
对于
Abandoned memory
,可以用Instrument
的Allocations
检测出来。检测方法是用Mark Generation
的方式,当你每次点击Mark Generation
时,Allocations
会生成当前App
的内存快照,而且Allocations
会记录从上回内存快照到这次内存快照这个时间段内,新分配的内存信息。举一个最简单的例子:我们可以不断重复
push
和pop
同一个UIViewController
,理论上来说,push
之前跟pop
之后,app
会回到相同的状态。因此,在push
过程中新分配的内存,在pop
之后应该被dealloc
掉,除了前几次push
可能有预热数据和cache
数据的情况。如果在数次push
跟pop
之后,内存还不断增长,则有内存泄露。因此,我们在每回push
之前跟pop
之后,都Mark Generation
一下,以此观察内存是不是无限制增长。用这种方法来发现内存泄露还是很不方便的:
- 首先,你得打开
Allocations
- 其次,你得一个个场景去重复的操作
- 无法及时得知泄露,得专门做一遍上述操作,十分繁琐
- 首先,你得打开
- Post title:性能优化01:内存泄漏检测
- Post author:张建
- Create time:2023-03-02 23:32:21
- Post link:https://redefine.ohevan.com/2023/03/02/OC性能优化/性能优化01:内存泄漏 2/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.