iOS App 内存专项实践

此篇是学习了 QCon 大会记录

iOS 是一个封闭的系统,使用的内存检测工具自然而然较少!

封闭系统下的工具 Instruments

苹果 Xcode 继承了 Instruments 供调试使用,但是这个工具对于测试人员来说其实并不可用,或者基本上是不可用的。开发者使用起来倒是顺手。

封闭系统下的自由


苹果系统自带的开发工具对于测试而言其实并不友好,苹果推崇的是开发、产品和测试集于一身的人员,而实际上这种倾向只适合于小的项目或者模块,模块一旦大了势必不是单打独头可以完成的,尤其是在大公司一个项目动辄编译半个小时,鉴于此就需要有适合于自动化集成的内存检测工具。

获取新建对象申请的内存地址和堆栈

  • 纯 OC 代码: 利用 method_exchangeImplementationse 接管 alloc 和 dealloc
  • C++ 内网版本(非纯 OC 代码): 借用开发工具的权限, malloc_logger 简单直接
  • C++ 外网版本: fishhook hook: malloc\calloc\free

获取指针变量

  • 堆区
  • 全局区
  • 栈区

剩下问题

内存泄漏的结果是:内存耗尽,闪退。除了内存泄漏之外还有没有其他的原因会造成闪退呢?

  • 大内存常驻
  • 内存越界
  • 侵略性内存使用,比如一次申请的内存空间很大

解决思路:

  • 记录申请的内存大小和堆栈
  • 记录堆栈内存的释放
  • 聚合数据

对上面的记录进行判断:

  • 单个申请的内存块大雨 50 MB
  • 申请内存(未释放)的综合大于阈值

针对内存越界,可以通过 address sanitizer 来进行检测:

  • Heap buffer overflow
  • Stack buffer overflow
  • Global buffer overflow
  • dangling pointer
  • Use-after-free
  • Double-free

最后记录:

  • 工具:Xcode、Address Sanitizer、Instruments
  • 界面声明周期
  • Xcode(malloc_logger)、LLDB
  • hook:fishhook、method_exchangeImplementations
  • hook 获取源码能力: fishhook 如何遍历 SECT_DATA 获取全局区
  • Jetsam
    Monkey 做自动化

总结:

这是一名测试工程师的分享,虽然没有实际的实现,但是原理已经讲明包括使用的工具以及有哪些方面,后面会慢慢去实践。

由这次学习有获得了两本书可以看:

  1. 《Mac OS X and iOS Internals 2012》
  2. 《Mac Os X Internals - A Systems Approach》

参考:
iOS App 内存专项实践

-------------本文结束谢谢欣赏-------------
Alice wechat