iOS 性能调试

作者: __Mr_Xie__ | 来源:发表于2019-06-10 17:47 被阅读29次

一、简介

性能调优的方式可以分为:

  • 通过专门的性能调优工具;
  • 通过代码优化;

二、内容

1、性能调优工具介绍

1.1、静态分析工具 – Analyze

相信 iOS 开发者在 App 进行 BuildArchive 时,会产生很多编译警告,这些警告是编译时产生的,静态分析的过程也类似,在 XCode Product 菜单下,点击 AnalyzeApp 进行静态分析。

Analyze 主要分析以下四种问题:
1、逻辑错误:访问空指针或未初始化的变量等;
2、内存管理错误:如内存泄漏;
3、声明错误:从未使用的变量;
4、API调用错误:未包含使用的库和框架。

1.2、内存泄漏分析工具 – Leaks

点击 XCodeProduct 菜单 Profile 启动 Instruments ,使用 Leaks 开始动态分析。
选择 Leaks ,会自动启动 Leaks 工具和 IOS 模拟器,Leaks 启动后会开始录制,随着对模拟器运行的 App 的操作,可以在 Leaks 中查看内存占用的情况。

注:如果项目使用了 ARC,随着操作,不断地开启或关闭视图,内存可能持续上升,但这不一定表示存在内存泄漏,ARC 释放的时机是不固定的。

Leaks 顶部分为两栏:All Heap & Anonymous VMLeaks ChecksAll Heap & Anonymous VM 中的曲线代表内存分配和内存泄漏曲线。

点击第二栏 Leaks Checks 展示内存泄漏,进行内存泄漏分析,将光标放置在上图的小红叉上可看到 leak 数量,右下方是leaks 调试的选项:

建议把 Snapshot Interval 间隔时间设置为10秒,勾选 Automatic SnapshottingLeaks 会自动进行内存捕捉分析。
在你怀疑有内存泄漏的操作前和操作后,可以点击 Snapshot Now 进行手动捕捉。
Leaked Object的表格中显示了内存泄漏的类型、数量及内存空间等。
点击具体的某个内存泄漏对象,在右侧 Detail 窗口中会出现导致泄漏可能的位置,其中 黑色头像(现在是蓝色头像) 代表了最可能的位置,具体使用可以参考我的文章 Instruments之Leaks的简单使用

内存泄漏动态分析技巧:

  • 熟练使用 Leaks 后会对内存泄漏判断更准确,在可能导致泄漏的操作里,多使用 Snapshot Now 手动捕捉。
  • 开始时如果设备性能较好,可以把自动捕捉间隔设置为 5 秒钟。
  • 使用 ARC 的项目,一般内存泄漏都是 malloc 、自定义结构、资源引起的,多注意这些地方进行分析。

开启ARC后,内存泄漏的原因:

  • 开启了ARC并不是就不会存在内存问题,苹果有句名言: ARC is only for NSObject
    iOS 中使用 malloc 分配的内存,ARC 是不会处理的,需要自己进行处理。
    例子中的 CGImageRef 也是一个 Image 的指针,ARC 也不会进行处理。
1.3 不合理内存分析工具 – Allocation

关于内存的问题,除了内存泄漏以外,还可能存在内存不合理使用的情况,也会导致 iOS 内存警告。

内存的不合理使用往往比内存泄漏更难发现,内存泄漏可以更多借助于工具的判断,而内存的不合理运用更多需要开发者结合代码、架构来进行分析。

明确说明一下两者的区别:

  • 内存泄漏:指内存被分配了,但是程序中已经没有指向该内存的指针,导致该内存无法被释放,一直占用着内存,产生内存泄漏。
  • 内存不合理运用:苹果官方称这种情况为 abandoned memory ,也就是存在已分配内存的引用,但实际上程序中并不会使用,比如图片等对象进行了缓存,但是缓存中的对象一直没有被使用。

Xcode 提供的 Instruments 中的 Allocation 工具可以用来帮你了解内存的分配情况,当你的 App 收到内存警告时,首先应该用Allocation 进行内存分析,了解哪些对象占用了太多内存。

1.4 干掉僵尸对象 – Zombies

僵尸对象,也就是我们会遇到的 EXC_BAD_ACCESS 错误,由于内存已经被释放,而这个对象仍旧保留这那个坏地址而导致的。
MRC 的开发中,这个错误比较常见,ARC 下面在使用到 C++ 的代码也会遇到。
不过这个工具比较简单,遇到这类错误,打开这个位于 Instruments 下的工具,直接就能帮你定位到,这里就不赘述了。

1.5 性能提升工具 – Time Profile

既然是性能调优,那么怎么提升代码的运行效率其实才是我们程序员最直接的诉求,而这个工具可以辅助我们办到这件事

Time Profiler 分析原理:
它按照固定的时间间隔来跟踪每一个线程的堆栈信息,通过统计比较时间间隔之间的堆栈状态,来推算某个方法执行了多久,并获得一个近似值。它将各个方法消耗的时间统计起来,形成了我们直接定位需要进行优化的代码的好帮手。

选择 Time Profiler 工具开始测试,这时会自动启动模拟器和 Time Profiler 录制。

  1. 先进行一些 App 的操作,让 Time Profiler 收集足够的数据,尤其是你觉得那些有性能瓶颈的地方。
  2. 是扩展面板,用来跟踪显示堆栈;
  3. 里面有设置和详情,可以从这里对录制做些配置, detail 下查看到 cpu 运行的时间都消耗在哪里;

    通过对应用的操作,可以在详细面板中看到那些最耗时的操作是哪些,并可以逐行展开查看:

图标为黑色头像的就是 Time Profiler 给我们的提示,有可能存在性能瓶颈的地方,可以逐渐向下展开,找到产生的根本原因。

Time Profiler 参数设置

这里边几个选项的含义如下:

  • Separate by Thread : 每个线程应该分开考虑。只有这样你才能揪出那些大量占用 CPU 的”重”线程
  • Invert Call Tree : 从上倒下跟踪堆栈,这意味着你看到的表中的方法,将已从第 0 帧开始取样,这通常你是想要的,只有这样你才能看到 CPU 中话费时间最深的方法.也就是说 FuncA{FunB{FunC}} 勾选此项后堆栈以 C->B-A 把调用层级最深的 C 显示在最外面
  • Hide System Libraries : 勾选此项你会显示你 app 的代码,这是非常有用的. 因为通常你只关心 cpu 花在自己代码上的时间不是系统上的
  • Flatten Recursion : 递归函数, 每个堆栈跟踪一个条目
  • Top Functions : 一个函数花费的时间直接在该函数中的总和,以及在函数调用该函数所花费的时间的总时间。因此,如果函数 A 调用 B ,那么 A 的时间报告在 A 花费的时间加上 B 花费的时间,这非常真有用,因为它可以让你每次下到调用堆栈时挑最大的时间数字,归零在你最耗时的方法。

上面的参数在实践中合理设置,也没有什么太多技巧,就是通过数据的隐藏、显示让我们更关注于想找到的数据。

2、性能调优之代码优化

2.1 views 设置为不透明 opaque=YES

opaque 这个属性给渲染系统提供了一个如何处理这个 view 的提示。如果设为 YES, 渲染系统就认为这个view是完全不透明的,这使得渲染系统优化一些渲染过程和提高性能。
如果设置为NO,渲染系统正常地和其它内容组成这个view。默认值是YES。
给你们看个图,你们就知道了,如果这个属性为NO,那么:


注:
2.2 持续更新中...

Author

如果你有什么建议,可以关注我的公众号:iOS开发者进阶,直接留言,留言必回。

相关文章

  • iOS 性能调试

    一、简介 性能调优的方式可以分为: 通过专门的性能调优工具; 通过代码优化; 二、内容 1、性能调优工具介绍 1....

  • iOS 调试

    iOS调试 - NSLog iOS调试 - 断点 iOS调试 - LLDB iOS调试 - EXC_BAD_ACC...

  • iOS app性能测试

    Instruments 介绍: 1.动态调试追踪和分析OSX和iOS的代码的性能和测试工具 2.支持多线程的调试 ...

  • iOS崩溃调试

    iOS崩溃调试 iOS崩溃调试

  • iOS高效调试

    iOS高效调试 iOS高效调试

  • React Native调试

    此处以iOS模拟器为例,Command+D打开开发者面板。 界面调试和性能监控 远程调试 在RN实例启动后,启动远...

  • iOS之性能调试Instruments(一)

    iOS性能调试有很多方法,这里讲一下Xcode内置工具Instruments。Instruments是一个官方提供...

  • iOS 性能优化

    ios性能优化(一)ios性能优化(二)ios性能优化(三)

  • iOS开发调试技巧总结

    iOS开发调试技巧总结 iOS开发调试技巧总结

  • iOS高级调试&逆向技术

    iOS高级调试&逆向技术 iOS高级调试&逆向技术

网友评论

    本文标题:iOS 性能调试

    本文链接:https://www.haomeiwen.com/subject/mgnaxctx.html