主要记录下用于分析iOS/macOS 内存问题的笔记。
主要分析命令: vmmap
, leaks
, malloc_history
一:前言
有 3 种思考方式
- 你想看到对象的创建吗?
- 你想要查看内存中引用对象或地址的内容吗?
- 或者你只是想看看 一个实例有多大?
如果你在进程启动时 启用了 malloc 堆栈日志记录, 那么 malloc_history
可以帮助你查找 该对象的回溯。
如果你只是想看看 在内存中引用对象的内容。 你可以使用 leaks
和在内存页面中 提供的其他工具来帮助你 。
最后 如果你只是想了解 一个区域或一个实例有多大 vmmap
和 heap
是首选工具 作为起始点。
我建议在进程的 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 size
和swapped size
才是我们需要关注的内容
dirty size
代表脏内存大小,我们app希望脏内存越小越好,最好都是clean内存
swapped size
iOS 中代表 压缩的内存,内存统计的是未压缩内存的大小。
app 使用的总内存一般为 =dirty size
+swapped size
-
vmmap --page app.memgraph | grep '.dylib'
对上面的内容只 看'.dylib'
动态库
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
四: Xcode 查看内存泄露
*.memgraph
还可以使用Instrument
和Xcode
打开进行分析.
双击app.memgraph
打开Xcode
后,
点击筛选可以单独查看内存泄露的内存