Allocation 概述
Allocation主要用于App检测内存分配和使用情况等,统计到的内存类型有All Heap & Anonymous VM(堆内存 和 虚拟内存)、All Heap Allocations(堆内存)、All Anonymous VM(虚拟内存),其中Anonymous VM(虚拟内存)是我们无法控制的部分,所以一般只关注All Heap Allocations(堆内存)。
在Allocation主要包含4类统计项:
- Statistics
- Call Trees
- Allocations List
- Generations
在Allocation最下方有两个筛选选项,分别是:
-
Allocation Lifespan:筛选需要记录的Allocation,一般我们只勾选Created & Persistent
All Allocations:所有的
Created & Persistent:创建且存活的
Created & Destroyed:创建且被销毁的
-
Allocation Type:记录Allocation的类型,一般关注All Heap Allocations较多
All Heap & Anonymous VM:所有真实内存和虚拟内存
All Heap Allocations:所有真实内存
All VM Regions:所有分配过的虚拟内存
Statistics 统计项
主要包含6个统计字段,分别对应的含义如下
Category:对象类型,包含Core Foundation对象、OC类、内存块
Persistent:当前活跃的内存总量
#Persistent:当前活跃的内存数量
#Transient:已经释放的内存申请数
Total Bytes:总字节数
#Total:申请内存总次数
Call Trees 统计项
这个功能是将列表展示类型切换成调用树的形式,如下所示,有3个统计项:
Bytes Used:相应方法使用的内存量
Count:方法被调用的次数
Symbol Name:方法名称
对应的在Call Trees下方还有三个配置项,下面分别来介绍
-
【调用过滤】Call Tree:配置调用树的显示,一般勾选1、3、4、5
调用过滤-
1、Separate by Category:按类别隔开,☑️后,可以更方便的看出是哪些类别的VM
Separate by Category -
2、Separate by Thread:按线程划分
Separate by Thread -
3、Invert Call Tree:反转调用,通俗来说就是从上倒下跟踪堆栈,例如FuncA{FunB{FunC}} 勾选此项后堆栈以C->B-A 把调用层级最深的C显示在最外面
-
勾选前
Invert Call Tree-选前 -
勾选后
Invert Call Tree-选后
-
-
4、Hide System Libraries:隐藏系统方法,因为目前我们只关心自定义的方法,这个是必选的
Hide System Libraries -
5、Flatten Recursion:递归函数,每个堆栈跟踪一个条目
Flatten Recursion
-
-
【数据过滤】Call Tree Constraints:主要是对列表中的数据进行过滤,可以设置最大/最小的数量和字节数
数据过滤-
配置前的列表
配置前 -
配置后的列表,例如配置只显示count为500以内的
配置后
-
-
【库/符号过滤】Data Mining:数据挖掘,简单来说就是可以过滤掉不看的库、符号调用,点击Symbol、Library会自动把你选中的行的符号、库加到小框中。例如选中start,点击symbol,就自动过滤了start相关列
库/符号过滤
其中Symbol(符号)和Library(库)有两个选项,即是否过滤改行,如果点击Restore会去掉小框中的选中行
选项
Allocations List 统计项
Adress:内存块的地址
Category:对象的类型
Timestamp:申请内存的时间
Size:内存块的大小
Responsible Library:负责申请该内存的库
Responsible Caller:负责申请该内存的方法
Generations 统计项
在Allocation中,可以通过对每个动作的前后进行Mark Generation,用来对比内存的增加,可以定位到内存增加的具体方法和代码所在位置。其中有4列统计项
Snapshot:快照名
Timestamp:快照时间
Heap Growth:自上次快照以来的增长数量
#Persistent:依旧存活的对象数量
这个功能非常有用,通常用在:进入一个页面前mark一下,在退出这个页面的时候再mark一下可以比较哪些内容增加了,就可以具体分析哪些内存没有被释放。具体操作如下所示
-
运行程序,点击底部Mark Generation,这样就生成一个Generation
Generation 当跳转到其他页面时,再生成一个Generation
-
然后查看生成的Generation的Growth的大小
Growth -
如果Growth太大,可以点进去查看占用较大线程中的代码块,点击Generation的箭头,进入具体的线程
具体的线程
使用
-
Xcode菜单 - Product - Profile - Allocation,并选择真机,对应项目,运行
路径
从截图中可以看出Heap为1.17MB,VM是1.16MB,在程序有需要时能提供足够的内存空间,并不是现在创建的。因此手机分配给App的内存是2.32MB。
-
一般选择Generation,分析不同页面的内存情况,需要多个mark generation,然后选择一个Generation,进入详情分析页面,
详情分析页面
主要关注堆内存,所以按内存分类,并隐藏系统函数
内存分类
从最上面可以看到堆内存+虚拟内存总共占了1.9MB,堆内存占了约1M,点开箭头查看具体的函数,然后点进去就可以看到内存激增的代码了,然后可以进行相应优化(由于是demo,所以不贴具体的代码图示了)
具体代码
参考文章
Instruments学习之Allocations
iOS性能分析-Xcode Instruments Allocations 分析APP内存使用情况
使用instrument-->Allocations进行内存分析