问题描述
我无法理解@autoreleasepool的工作方式.考虑下面的示例,在该示例中,我为音频文件创建AVAssetReader.为了使内存的影响变得重要,我重复了此步骤1000次.
I'm having trouble understanding how @autoreleasepool work. Consider the following example in which I am creating an AVAssetReader for an audiofile. To make the memory impact matter, I repeated this step 1000 times.
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
void memoryTest() {
NSURL *url = [[NSURL alloc] initWithString:@"path-to-mp3-file"];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset error:NULL];
}
int main(int argc, const char * argv[]) {
// Breakpoint here (A)
@autoreleasepool {
for(int i = 0; i < 1000; i++) {
memoryTest();
}
}
// Breakpoint here (B)
return 0;
}
在断点A和断点B循环之前和之后,我在Xcode Debug Navigation中查看了我的应用程序的内存使用情况.在A点,我的应用程序消耗了约1.5MB的内存.在B点,它约为80MB.有趣的是,当我将autoreleasepool放入循环中时,B处的内存使用量下降到约4MB,如下所示:
Before and after the loop at breakpoint A and breakpoint B I took a look at the memory usage of my application in the Xcode Debug Navigation. At point A my App consumes about 1.5MB of memory. At point B it is about 80MB. Interestingly the memory usage at B drops to about 4MB when I put the autoreleasepool inside the loop like so:
for(int i = 0; i < 1000; i++) {
@autoreleasepool { memoryTest(); }
}
职位为何重要? (在两种情况下,断点都在autoreleasepool之外!)在任何一种情况下,B点消耗的内存都与循环数成正比.我在这里想念其他东西来释放它的记忆吗?
Why does the position matter? (The breakpoint - in both cases - is outside of the autoreleasepool!) In either case the consumed memory at point B is proportional to the number of loops. Am I missing something else here to free up its memory?
我认为导航器中的内存图表会被延迟,但是在断点之前添加usleep不会改变任何内容.如果我将memoryTest()更改为
I thought of the memory chart in the navigator to be delayed, but adding usleep just before the breakpoint does not change anything. If I change memoryTest() to
void memoryTest() {
NSURL *url = [NSURL URLWithString:@"path-to-mp3-file"];
}
@autoreleasepool的位置无关紧要.那不是很奇怪吗?
the position of @autoreleasepool does not matter. Isn't that weird?
我正在使用启用了ARC的Xcode 6,OS X SDK 10.10.
I am using Xcode 6, OS X SDK 10.10 with ARC enabled.
推荐答案
您的代码会通过循环内的代码创建并自动释放临时内存,并调用该API进行调用.直到池耗尽后才释放此内存.排空的通常点是在运行循环中.但是您的循环不允许run循环执行,因此通过将@autoreleasepool放入循环中,池可以在代码运行时耗尽.
Temporary memory is being created and autorelease'ed by the code inside the loop by your code and the API calls it makes. This memory is not released until the pool is drained. The usual point it is is drained is in the run loop. But your loop does not allow the run loop to execute so by placing the @autoreleasepool inside the loop the pool can drain as your code runs.
这篇关于为什么@autoreleasepool的位置很重要?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!