ios 内存深度优化_iOS 使用Instruments优化内存性能

本文以项目中图片合成视频时内存增长迅速的问题为例,介绍使用Instruments工具检测和分析内存问题。通过该工具查看内存增长区域、堆内存分配详细数据等,分析得出image对象释放不及时导致内存增长,最终在while循环内使用autoreleasepool块解决问题,使内存增长大幅下降。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

iOS 使用Instruments优化内存性能

问题

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

Instruments检测

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

打开Instruments选择Allocations工具,点击录制按钮进行录制

使用鼠标框选出内存增长的区域,图中两条黑线中的高亮区域

上面图表区域是内存的可视化视图

下面的面板区域显示的是具体的统计数据

可以看到整体的内存增长为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

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

内存增长为492K

由上可知,使用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代码 ScreenRecorderTest2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值