0

我有一个保留/发布项目,它有一个简单的算法。我从一个 100000 个对象的可变数组开始,每隔 5 秒我在开始时删除 1000 个对象并在最后添加 1000 个对象。从理论上讲,我的内存占用应该在 Lil 延迟后保持不变,但是它会持续上升,直到达到一定数量。但是用“[array removeAllObjects]”删除它的所有对象并释放数组并不会回收所有内存,只是一部分。我在发布方案中运行,没有调试器,并使用活动监视器来跟踪内存使用情况。

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
    array = [[NSMutableArray alloc] init];
    for(int i = 0; i<100000; i++){
        NSURL *url = [NSURL URLWithString:@"http://www.apple.com"];
        [array addObject:url];
    }
    self.t = [NSTimer scheduledTimerWithTimeInterval:10  target:self selector:@selector(addAndRemove:) userInfo:nil repeats:YES];

}

-(IBAction)addAndRemove:(id)sender{
     [array removeObjectsInRange:NSMakeRange(0, 1000)];

     for(int i = 0; i<1000; i++){
        NSURL *url = [NSURL URLWithString:@"http://www.apple.com"];
        [array addObject:url];
     }
}

-(IBAction)clear:(id)sender {
    [array removeAllObjects];    
    [array release];
    [t invalidate];
    t = nil;
}
4

2 回答 2

3

当您使用创建 NSURL

NSURL *url = [NSURL URLWithString:@"http://www.apple.com"];

您正在创建一个 Autoreleased 对象。自动释放的对象被存储在自动释放池中,并且只有在该池被清空时才会被销毁。当主运行循环触发时,主池每 60 秒刷新一次,因此您的对象释放的时间可能比您预期的要晚。

尝试将您的 for 循环包装在 @autoreleasepool { } 块中,以便立即刷新在循环内创建的任何自动释放对象,或者使用 alloc/init 创建您的 NSURL 以便它不会自动释放,例如

NSURL *url = [[NSURL alloc] initWithString:@"http://www.apple.com"];

然后看看这是否会改变您的内存使用情况。

于 2012-04-18T22:46:20.367 回答
3

使用 Activity Monitor 监控内存使用情况非常不可靠。首先,您在看哪个内存领域(虚拟私有内存、真正私有内存、真正共享内存或真实内存)?

其次,当您的代码发出分配请求时,通常会直接或间接地发送到 malloc 例程。malloc 例程尝试从它已经拥有的内存中满足您的请求。如果它不能,那么它会向系统请求更多。当您释放内存时,它会返回到 malloc。Malloc 不一定会将其返回给系统。它可以让它更快地满足未来的请求。因此,您可能不会看到进程的内存使用量下降,至少不会一直下​​降,即使您的程序正在释放它分配的所有内容。

检查程序是否正确管理内存的正确方法是将 Instruments 与 Leaks and Allocations 工具一起使用。

于 2012-04-18T23:00:32.767 回答