为了测试内存管理和分配,我编写了一个简单的 Single View 应用程序,viewDidAppear
为了创建一个包含许多对象的长循环,我编写了以下代码:
- (void) viewDidAppear:(BOOL)animated
{
NSDate * time = [NSDate date];
[super viewDidAppear:animated];
for (int i = 0; i < 20003; i++)
{
NSString * testString = [[NSString alloc] initWithString:@"This is a test string"];
NSMutableArray * itemsArray = [[NSMutableArray alloc] init];
for (int j = 0; j < 1000; j++)
{
[itemsArray addObject:testString];
}
if ((i % 1000) == 0)
{
NSLog(@"called %d", i);
}
}
NSDate * time2 = [NSDate date];
NSTimeInterval interval = [time2 timeIntervalSinceDate:time];
[label2 setText:[NSString stringWithFormat:@"time interval: %f", interval]];
}
在分析内存泄漏时,正如预期的那样,存在内存泄漏和超过 260 MB 的分配,屏幕截图:
但是在关注本文档时,我将代码更改为:
- (void) viewDidAppear:(BOOL)animated
{
NSDate * time = [NSDate date];
[super viewDidAppear:animated];
for (int i = 0; i < 20003; i++)
{
@autoreleasepool
{
NSString * testString = [NSString stringWithFormat:@"%@", @"This is a test string"];
NSMutableArray * itemsArray = [[NSMutableArray alloc] init];
for (int j = 0; j < 1000; j++)
{
[itemsArray addObject:testString];
}
[itemsArray release];
itemsArray = nil;
if ((i % 1000) == 0)
{
NSLog(@"called %d", i);
}
}
}
NSDate * time2 = [NSDate date];
NSTimeInterval interval = [time2 timeIntervalSinceDate:time];
[label2 setText:[NSString stringWithFormat:@"time interval: %f", interval]];
}
分配量仍然没有差异,但没有内存泄漏,执行时间明显增加,从不到 2 秒增加到 80 秒左右:
并且仍然在使用发布后,没有任何变化。代码:
- (void) viewDidAppear:(BOOL)animated
{
NSDate * time = [NSDate date];
[super viewDidAppear:animated];
for (int i = 0; i < 20003; i++)
{
NSString * testString = [[NSString alloc] initWithString:@"This is a test string"];
NSMutableArray * itemsArray = [[NSMutableArray alloc] init];
for (int j = 0; j < 1000; j++)
{
[itemsArray addObject:testString];
}
[testString release];
testString = nil;
[itemsArray release];
itemsArray = nil;
if ((i % 1000) == 0)
{
NSLog(@"called %d", i);
}
}
NSDate * time2 = [NSDate date];
NSTimeInterval interval = [time2 timeIntervalSinceDate:time];
[label2 setText:[NSString stringWithFormat:@"time interval: %f", interval]];
}
和截图:
并且明确地清空 MutableArray(使用[itemsArray release]
)显示没有任何变化。
我的问题是:
为什么在这三种情况下分配的总内存没有变化(尽管在第二种和第三种情况下没有内存泄漏),有没有办法减少大分配的内存?故障在哪里,如何减少内存消耗?
其次,我是否使用了正确的工具并读取了正确的数字(在 Profiler Instruments 中使用 Memory Leaks,并参考 All Allocations,在分配生命周期中,选择 created and still living),我是否以正确的方式进行操作?我的意思是这是目前消耗的内存量,还是自应用程序启动以来消耗的总内存量?
为什么在第二种情况下循环执行时间显着增加,而不是在第一种和第三种情况下?
使用 xCode 4.5,没有 ARC,没有 StoryBoards,所有测试都是在模拟器上完成的。