博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 使用Instruments优化内存性能
阅读量:5820 次
发布时间:2019-06-18

本文共 2327 字,大约阅读时间需要 7 分钟。

hot3.png

iOS 使用Instruments优化内存性能

问题

项目中使用到图片合成视频,发现内存增长十分的迅速,导致一些因为内存引起的问题,本文使用这个案例,结合Instruments工具检测和分析问题,最终解决内存问题。

本文的Demo代码

Instruments检测

查看某个范围内的内存增长

  1. 打开Instruments选择Allocations工具,点击录制按钮进行录制
  2. 使用鼠标框选出内存增长的区域,图中两条黑线中的高亮区域

查看某个范围内的内存增长

  • 上面图表区域是内存的可视化视图
  • 下面的面板区域显示的是具体的统计数据
    可以看到整体的内存增长为16.81M (All Heap Allocations 堆内存的分配)

堆内存分配的详细统计数据

点击All Heap Allocations旁边的小箭头按钮可以看堆内存分配的详细统计数据: 堆内存分配的详细统计数据

  • Address:数据的内存地址
  • Timestamp:数据创建的时间
  • Size:数据的大小
  • Responsible Library:数据创建的相关的库
  • Responsible Caller:数据创建的相关的库的函数调用

统计数据表中可以看出AppleJPEG 库调用 applejpeg_decode_create 方法创建了很多的内存的数据


 右边区域显示的是函数的调用栈信息面板(Stack Trace),右上角的工字型按钮可以切换显示系统函数调用
切换显示系统函数调用

内存分配大小与对应的代码调用信息的可视化显示

点击调用栈中的高亮代码可以查看代码详情和内存信息:
内存分配大小与对应的代码调用信息的可视化显示

右边的标注区域显示的是内存占用的比例。

分析

上图中看到buffer对象和image占用的内存最大,但是buffer在每次使用之后都会调用CVPixelBufferRelease释放对应的内存,不会有内存的问题,image对象释放的不及时,会在整个while循环块中保留一段时间,导致内存的增长。

此外image对象释放不及时和在在同一时间调用CVPixelBufferRelease(buffer);释放buffer也有关系,如果没有创建buffer和释放buffer的操作,image对象的增长也不会很明显,释放的速度也挺快,下面两个对照组可以进行对比分析

对照组1:只有在循环中创建image对象内存增长:

内存增长为2.73M
对照组1:只有在循环中创建image对象内存增长:

对照组2:在循环中添加autoreleasepool创建image对象内存增长:

内存增长为492K
对照组2:在循环中添加autoreleasepool创建image对象内存增长

由上可知,使用autoreleasepool可以有效的解决在某个循环中创建大量的内存敏感型对象导致的内存上涨的问题

最终解决方案

在while循环内部使用autoreleasepool块,每次循环arc对象得以及时的释放,内存增长从原来的16.81M下降到了只有475K
最终解决方案

代码:

while(i < imageNames.count) {    // 添加自动释放池,让内存敏感型的对象(UIImage)及时释放    @autoreleasepool {       // 代码省略...        NSString *imageName = [imageNames objectAtIndex:i];        NSString* imagePath = [imageSavedDir stringByAppendingPathComponent:imageName];        UIImage* image = [UIImage imageWithContentsOfFile:imagePath];        if(adaptor.assetWriterInput.readyForMoreMediaData) {            i++;            CMTime frameTime = CMTimeMake(1, fps);            CMTime lastTime = CMTimeMake(i, fps);            CMTime presentTime = CMTimeAdd(lastTime, frameTime);                        buffer = [self pixelBufferFromCGImage:[image CGImage] size:videoFrameSize];            // 写入视频            BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];            if(buffer) {                CVPixelBufferRelease(buffer);            }            // 代码省略...            [NSThread sleepForTimeInterval:0.05];        } else {            NSLog(@"Error: Adaptor is not ready");            [NSThread sleepForTimeInterval:0.05];            i--;        }    }}

总结

以上是使用Instruments解决内存问题的总结,如有不妥之处还请不吝赐教

本文的Demo代码

转载于:https://my.oschina.net/FEEDFACF/blog/1620259

你可能感兴趣的文章
[HTML]TD中的文本自动换行
查看>>
理解load average和cpu使用率
查看>>
有手机输入键盘时切换横竖屏高度变化的问题
查看>>
go语言中net包tcp socket的使用
查看>>
php捕获Fatal error错误与异常处理
查看>>
Ext JS 4.1.1 (GA)发布
查看>>
mongodb主从环境搭建(包含keepalive)
查看>>
12、《每天5分钟玩转Docker容器技术》学习-Docker命令之容器操作命令
查看>>
我的友情链接
查看>>
eclipse如何绑定jre
查看>>
iptables防火墙配置详解
查看>>
Qt的QGridLayout按比例设定布局
查看>>
vim实用技巧
查看>>
gearman 安装配置
查看>>
2016年投资回顾
查看>>
使用nova boot命令创建openstack实例
查看>>
cocos2dx[3.2](3) ——大巨变3.x
查看>>
我的友情链接
查看>>
备份windows共享目录与共享权限
查看>>
LINUX REDHAT第五单元文档
查看>>