美文网首页
性能优化小记

性能优化小记

作者: hiseason | 来源:发表于2018-02-25 11:45 被阅读26次

FPS

全称Frames Per Second,其实就是屏幕刷新率,苹果的iphone推荐的刷新率是60Hz,也就是说GPU每秒钟刷新屏幕60次,这每刷新一次就是一帧frame,FPS也就是每秒钟刷新多少帧画面。静止不变的页面FPS值是0,这个值是没有参考意义的,只有当页面在执行动画或者滑动的时候,FPS值才具有参考价值,FPS值的大小体现了页面的流畅程度高低,当低于45的时候卡顿会比较明显。

1.内存泄露检测

方法一: 使用 instrument 检测

Analyze

静态分析查找可疑的内存泄露

1.内存泄露
oc 对象存放在堆区, 堆区是需要程序员管理的, 如果使用变量之后没有释放变量所占用的内存空间(即这块空间没有指针指向), 导致这块空间不能再被回收使用, 这就叫内存泄漏.
2.什么情况下会发生内存泄漏?
*block 的循环引用
*潜在的内存泄露:这里主要是一些非OC对象,ARC不会对它进行释放,所以造成了一直没有释放。比如一些类型:CGImageRef(对应调用CGImageRelease)、CGContextRef(对应调用CGContextRelease)CGColorSpaceRef(对应CGColorSpaceRelease) 这些都是非OC对象,所以要自己记着释放掉。

使用方法:
1.菜单 product-Analyze
2.点击左侧感叹号就可看到分析结果,如下图

image.png
蓝色线的地方就是使用 Analyze 静态分析查找出来的泄漏点,称之为"可疑泄漏点".之所以称之为"可疑泄漏点",是因为这些点未必一定泄露,确认这些点是否泄露, 还要通过 Instruments 动态分析工具的 Leaks 和 Allocations 跟踪模板. Analyze 静态分析只是一个理论上的预测过程.
Leaks
使用方法.png 设置.png

方法二: MLeaksFinder

腾讯开发的 MLeaksFinder 使用很方便, 详细了解移步于此 MLeaksFinder:精准 iOS 内存泄露检测工具, 下面介绍一下我的使用过程, 分享一些内存泄露的例子.

1.1 UIAlertController 泄露
泄露截图.png

思路

  1. 在 viewController 中使用 dealloc 方法检测, 发现控制器没有被销毁,也出现了内存泄漏。猜测是UIAlertController 对控制器进行强引用。 看看我的代码,看出来问题出在哪里了吧!
    UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:nil  message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"相机" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self judgeAuthorization];
    }];

    UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"去相册选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
        [self showImagePickerController];
    }];

    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        [alertVc dismissViewControllerAnimated:YES completion:nil];
    }];

    [alertVc addAction:action1];
    [alertVc addAction:action2];
    [alertVc addAction:cancelAction];
    [self presentViewController:alertVc animated:YES completion:nil];

是block的循环引用导致了内存泄漏,解决办法就是用`__weak typeof(self) weakSelf = self;

    [weakSelf judgeAuthorization];
    [weakSelf showImagePickerController];
循环引用示意图.png
  1. vc 的内存泄露解决了,不过在点击确定类 Action push 到下一个 vc 时, 仍然报alertVc 内存泄露, 如何证明呢?相信你也一定想到,写一个类继承自UIAlertController 看看有没有走dealloc方法...... 然而.....真的没有。

想了一下, 原来是因为[self presentViewController:alertVc animated:YES completion:nil] vc 对 alertVc 在进行着强引用, 而 vc 还没有被释放, 所以 alertVc 无法释放。在 Google 后找到解决办法, 声明全局变量, 修改 dismiss 时的 alertVc。

 @property (strong, nonatomic) XSAlertController *alertController;     
  [weakSelf.alertController dismissViewControllerAnimated:YES completion:nil];
  //之前是 [alertVc dismissViewControllerAnimated:YES completion:nil];

在pop alertVc 所在的 vc 时, alertVc 调用了 dealloc 方法, MLeaksFinder 又弹框了, 没有泄漏 MLeaksFinder 为什么还弹框, 难道是我释放多了一次?
莫慌, 其实是 MLeaksFinder 的友情提示, 告诉你刚刚内存泄漏的对象现在已经正常释放了,详细的解释请看这里MLeaksFinder 新特性

内存泄露的对象已经释放了.png

2. 启动时间优化

在 scheme 中添加 DYLD_PRINT_STATISTICS 设置为1

DYLD_PRINT_STATISTICS.png

输出控制台会显示时间


console.png

3. UI 卡顿优化

CPU 资源消耗原因和解决方案
对象创建
对象的创建会分配内存、调整属性、甚至还有读取文件等操作,比较消耗 CPU 资源。尽量用轻量的对象代替重量的对象,可以对性能有所优化。比如 CALayer 比 UIView 要轻量许多,那么不需要响应触摸事件的控件,用 CALayer 显示会更加合适。如果对象不涉及 UI 操作,则尽量放到后台线程去创建,但可惜的是包含有 CALayer 的控件,都只能在主线程创建和操作。通过 Storyboard 创建视图对象时,其资源消耗会比直接通过代码创建对象要大非常多,在性能敏感的界面里,Storyboard 并不是一个好的技术选择。

Allocations

查看内存分配

All Heap Allocations: 真实内存
All Anonymous VM: 虚拟内存, 为程序分配的虚拟内存,当程序有需要的时候,能够及时为程序提供足够的内存空间,而不会现用现创建

在我的项目中进行选择相册照片的操作, 内存分配如图所示, 红框选中的就是虚拟内存项


虚拟内存.png

VM:CG raster data
关于这个问题我在google中找到了解释,这是SDWebImage的问题

  • Decompressing images that are downloaded and cached can improve peformance but can consume lot of memory.
  • Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption.
//所以我们需要在Appdelegate中设置一下
[SDImageCache sharedImageCache].config.shouldDecompressImages = NO;

Time Profiler

检测应用CPU的使用情况

注意点:
(1)使用真机调试。
(2)最好使用release包测试(release是发布版本,苹果会在release包中做很多优化工作,因此用release包测试出来的性能才是最真实的)。

相关文章

  • 性能优化小记

    FPS 全称Frames Per Second,其实就是屏幕刷新率,苹果的iphone推荐的刷新率是60Hz,也就...

  • Android性能优化 - 消除卡顿

    性能优化系列阅读 Android性能优化 性能优化 - 消除卡顿 性能优化 - 内存优化 性能分析工具 - Tra...

  • Android性能优化 - 内存优化

    性能优化系列阅读 Android性能优化 性能优化 - 消除卡顿 性能优化- 内存优化 性能分析工具 - Trac...

  • 前端性能优化(中)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 《前端性能优化(上)...

  • 前端性能优化(下)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 《前端性能优化(中)...

  • TableView性能优化——小记

    1,CPU考虑,使用懒加载的方式创建控件 2.提前计算并缓存Cell的高度 3.图片的圆角与透明度处理,尽量避免触...

  • JavaScript 性能优化小记

    加载与运行 延期脚本 js文件要在dom加载完成时才会被下载 动态脚本元素 var script= d...

  • Awesome Extra

    性能优化 性能优化模式 常见性能优化策略的总结 Spark 性能优化指南——基础篇 Spark 性能优化指南——高...

  • 常用的后端性能优化六种方式:缓存化+服务化+异步化等

    性能优化专题 前端性能优化 数据库性能优化 jvm和多线程优化 架构层面优化 缓存性能优化 常用的后端性能优化六大...

  • webpack 性能优化

    webpack性能优化 开发环境性能优化 生产环境性能优化 开发环境性能优化 优化打包构建速度 优化调试功能 生产...

网友评论

      本文标题:性能优化小记

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