在帧写入循环中使用和不使用自动释放池的内存占用,为啥?

Posted

技术标签:

【中文标题】在帧写入循环中使用和不使用自动释放池的内存占用,为啥?【英文标题】:Memory footprint with and without autoreleasepool in a frame writing loop, why?在帧写入循环中使用和不使用自动释放池的内存占用,为什么? 【发布时间】:2013-07-29 04:26:20 【问题描述】:

我正在分析一个 avfoundation 视频编码程序。内存随着帧的写入而增加。添加自动释放池后,问题就消失了。

        @autoreleasepool 

            NSString *inputFramePath = self.inputFramePaths[self.currentFrameIndex++];
            self.currentFrame = [UIImage imageWithContentsOfFile:inputFramePath];

            CVPixelBufferRef buffer = (CVPixelBufferRef)[VideoExporter newPixelBufferFromCGImage:self.currentFrame.CGImage size:self.resolution];
            if (buffer) 
                [self.adaptor appendPixelBuffer:buffer withPresentationTime:self.nextPTS];
                CVPixelBufferRelease(buffer);
                self.nextPTS = CMTimeAdd(self.frameDuration, self.nextPTS);
            
        

没有自动释放池:

使用自动释放池:

我对 autoreleasepool 还不是很清楚,谁能解释一下我的代码中到底发生了什么?我是否需要批量写入帧而不是为每一帧耗尽池?

【问题讨论】:

【参考方案1】:

当您自动释放一个对象时,它会被添加到一个自动释放池中。通常,添加到的池是在堆栈中创建的池,并作为运行循环的一部分(对于在主线程上为您创建的池)或线程退出时(当您在一个线程的开始)

通过在其他地方创建自动释放池,其作用域内的自动释放对象会在该池耗尽时被释放,而不是等待现有的对象耗尽。在循环处理大量数据的情况下,这可以显着降低内存使用的高水位线。

通过一组图像进行处理可能是此类用例之一。就您而言,我猜您的代码示例是一次处理多个帧的循环的一部分。

只要你需要在自动释放池之外的所有对象都被保留,那么它就可以安全使用。

请务必阅读 Advanced Memory Management Programming Guide 关于自动释放池的部分。

【讨论】:

以上是关于在帧写入循环中使用和不使用自动释放池的内存占用,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

带有自动释放池的@property 复制和手动内存管理

main.m 真的是每个事件创建主运行循环的自动释放池的地方吗?

SharePoint 2016 每天预热脚本介绍

在sql server 2000中进行内存的自动释放怎么实现?拜托各位了 3Q

sql 2008 R2 怎样 释放内存

解决w3wp.exe占用CPU和内存问题