深入了解iOS内存(WWDC 2018)笔记-内存诊断

主要记录下用于分析iOS/macOS 内存问题的笔记。
主要分析命令: vmmap, leaks, malloc_history

一:前言

有 3 种思考方式

  • 你想看到对象的创建吗?
  • 你想要查看内存中引用对象或地址的内容吗?
  • 或者你只是想看看 一个实例有多大?

如果你在进程启动时 启用了 malloc 堆栈日志记录, 那么 malloc_history 可以帮助你查找 该对象的回溯。
如果你只是想看看 在内存中引用对象的内容。 你可以使用 leaks 和在内存页面中 提供的其他工具来帮助你 。
最后 如果你只是想了解 一个区域或一个实例有多大 vmmapheap 是首选工具 作为起始点。
我建议在进程的 Memgraph 上 运行带有 -summary 命令的 vmmap 然后顺着线程继续进行.

二:准备: 生成 .memgraph 文件

下面两种方法二选一,命令行适合不适用Xcode调试的时候。

1. Xcode 导出内存图

勾选Malloc Statck Logging ,这样 malloc_history 才有效果。
在这里插入图片描述

xcode 导出 .memgraph
在这里插入图片描述

在这里插入图片描述
2. 使用命令行行导出内存图
wwdc 上说明了,MallocStackLogging=lite 或者 MallocStackLogging=1, 两种模式,我们选择lite模式,和Xcode选择的一样
在这里插入图片描述

terminal 设置环境遍量并启动app:

$ export MallocStackLogging=lite && open /Applications/xxxx.app

app启动后,在合适的时间点抓取内存快照,存入本地文件中:
在这里插入图片描述
本地使用命令:
$ leaks PRISMLiveStudio --outputGraph ~/Desktop/test/memgraph/testapp.memgraph

最终效果:
在这里插入图片描述

三:分析内存使用的命令

vmmap

  • vmmap --summary app.memgraph
    dirty sizeswapped size 才是我们需要关注的内容
    dirty size 代表脏内存大小,我们app希望脏内存越小越好,最好都是clean内存
    swapped size iOS 中代表 压缩的内存,内存统计的是未压缩内存的大小。
    app 使用的总内存一般为 = dirty size + swapped size
    请添加图片描述
    输出底部:
    在这里插入图片描述

  • vmmap --page app.memgraph | grep '.dylib'
    对上面的内容只 看 '.dylib' 动态库
    在这里插入图片描述

  • vmmap --page xxxx.memgraph | egrep "MALLOC_SMALL|REGION TYPE"
    在这里插入图片描述

leaks

  • leaks app.memgraph 命令查看无根内存,代表这不能被释放的无根内存(macOS适用)
  • leaks -traceTree 0x000000014b9b4000 PlanetPics.memgraph

在这里插入图片描述

heap

  • heap App.memgraph 查看堆对象
  • heap App.memgraph -sortBySize 按分配的大小排序,找出内存最大的那个元素,比如NSConcreteData
  • heap App.megraph -addresses all | ‹classes-pattern> 直接查找上一步NSConcreteData的具体数据 heap App.megraph -addresses NSConcreteData
  • heap --quiet App.memgraph --address "NSConcreteData.*[10M-]", 使用通配符,直接找到大于10M的NSConcreteData对象,这非常有用,其他几个工具的 --address 同样适用这个逻辑
  • heap log_start_4.16_08.43.memgraph --diffFrom log_start_4.15_14.21.memgraph -s, diffFrom 比较两个的差别。

malloc_history

  • malloc_history app.memgraph [address] 找到上一步的有问题的其中一个地址,进行堆栈跟踪
    leaks -traceTree 0x000000014b9b4000 PlanetPics.memgraph
  • malloc_history PlanetPics.memgraph --fullStacks 0x000000014b9b4000
    在这里插入图片描述

综合使用

  1. vmmap --summary app.memgraph -sortBySize 找出异常大小的模块,
  2. 比如异常大小为 MALLOC_SMALL 的子类型 MallocStackLoggingLiteZone_0x10fb28000, 则使用 vmmap --page xxxx.memgraph | egrep "MallocStackLoggingLiteZone_0x10fb28000|REGION TYPE" 查找具体malloc的 类。但是此时拿到的 511800000-512000000 页地址,可能不能用作malloc_history 的分析。
  3. 即使2不能回溯堆栈,但是确认了内存是malloc 出来的, 那么我们使用 heap App.memgraph -sortBySize 找到有异常的 malloc 类。
    在这里插入图片描述
  4. 可以通过上面的命令看到 cef_time_delta in cef_time_delta 是异常的地方,申请 总内存5452987312 转换为5GB, 并且数量也很多,平均5358Bytes转换为5KB, 说明内存申请频繁而小。
  5. 根据上面判断的平均malloc的大小,以及malloc的类型,我们可以组合使用这个命令。heap 最后的.memgraph --diffFrom 开始的.memgraph -addresses "cef_time_delta in cef_time_delta.*[8K-]", 比较两个文件,新增的“cef_time_delta in cef_time_delta” 内存,并且是大于8k的内存

在这里插入图片描述
6. 这里我们可以将地址拿出来,比如0x118bc0000, 然后运行 malloc_history xxx.memgraph -fullStacks 0x118bc0000 命令查看具体堆栈在这里插入图片描述
7. 上一步的内存地址很多的情况,也可以写python 脚本(memgraph_address_to_stack.py),开启多进程批量分析,然后将结果进行合并展示。

四: Xcode 查看内存泄露

  • *.memgraph 还可以使用 InstrumentXcode 打开进行分析.

双击app.memgraph 打开Xcode后,
点击筛选可以单独查看内存泄露的内存
在这里插入图片描述

链接: https://developer.apple.com/wwdc18/416

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值