Objective-C内存没有被大型数组释放

时间:2010-01-13 23:06:40

标签: objective-c memory-management

我正在使用Cocoa开发一个程序,希望尽可能使用最少的内存。为了检查这一点,我一直在使用Activity Monitor。我的程序有一个相当大的NSMutableArray包含NSString的实例,当我释放数组时,我没有得到所有的回忆。以下示例演示了我的问题。

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:10];

    NSLog(@"The array has no elements!"); // Activity monitor says 1.5 megs
    [NSThread sleepForTimeInterval:10];

    NSUInteger i;
    for(i = 0;i < 1000000;i++)
    {
        NSString *str = [[NSString alloc] initWithFormat:@"Number=%d, again it is: %d, one more time for added length: %d", i, i, i];
        [array addObject:str];
        [str release];
    }

    NSLog(@"We have used lots of memory!"); // Activity Monitor says 108 megs
    [NSThread sleepForTimeInterval:5];

    [array release];
    NSLog(@"We have released the array!"); // Activity Monitor says 19 megs
    [NSThread sleepForTimeInterval:5];

    [pool drain];
    NSLog(@"We have drained the pool!"); // Activity Monitor still says 19 megs
    [NSThread sleepForTimeInterval:5];

    return 0;
}

我添加了对sleepForTimeInterval的调用,因此我可以看到并记录Activity Monitor列出的内存使用情况。在每次暂停时我都列出了我应该使用的内存量。我几乎可以肯定我的问题源于保留/发布约定中的误解。有谁看到我哪里出错了?

3 个答案:

答案 0 :(得分:4)

您的代码是正确的。

我建议使用Instruments检查对象分配。您应该看到释放阵列时已取消分配所有内容。

您在Activity Monitor中看到的数字可能是由Foundation执行的某些NSString内存缓存的结果,或者它可能只是操作系统内存管理器正在处理您的应用程序的功能。

答案 1 :(得分:1)

然后,我只是写了一个完整的答案,错过了你的[str release]电话:)

无论如何,您实际上并没有使用自动释放池,因为您自己手动分配所有内容。如果您改为使用[NSString stringWithFormat...],然后释放字符串,那么您将使用自动释放池。

答案 2 :(得分:-1)

在运行循环之间清理内存。

[NSThread sleepForTimeInterval:n] 

阻塞线程,不会发生运行循环处理。

http://developer.apple.com/mac/library/documentation/cocoa/reference/Foundation/Classes/NSThread_Class/Reference/Reference.html#jumpTo_12

你不是专门解除内存释放,你只是将保留计数减少到0,这将允许运行时在运行循环的下一次迭代中清理内存。

“在此期间自动释放的对象将在运行循环周期结束时销毁......”

http://parmanoir.com/When_does_autorelease_release_%3F