Objective-C重用NSString内存泄漏

use*_*972 2 memory cocoa memory-leaks objective-c nsstring

我编写了一个非常简单的测试应用程序来尝试帮助我正在开发的更大的项目.

简单地说,测试应用程序循环预定次数并在每个循环上向字符串附加"1".当循环达到1000的倍数时,将重置该字符串并重新开始该过程.

代码如下; 但我发现内存使用量远高于我的预期.每次迭代增加约0.5MB.

似乎newString没有被重用,但是被丢弃并且创建了一个新实例,而没有恢复它正在使用的内存.

最终,该软件需要计数远高于100000.作为测试,如果我将迭代更改为1000万,它将占用超过5GB的内存!

有人有什么建议吗?到目前为止,我有各种方法来编写字符串清除并关闭ARC并手动释放它/重新创建,但似乎没有一种方法可以回收我期望的内存量.

感谢您的任何帮助!

*PS.是的,这个实际的软件完全没有意义,但正如我所说,它是一个测试应用程序,一旦修复就会迁移到一段有用的代码中.


int targetCount = 100000;
NSString * newString;

int main(int argc, const char * argv[]) {
   @autoreleasepool {
      process();
      return 0;
    }
}

void process() {
    for (int i=0; i<targetCount; i++) {
        calledFunction(i);
    }
}

void calledFunction(count) {
    if ((count % 1000) == 0) {
        newString = nil;
        newString = @"";
    } else {
        newString = [NSString stringWithFormat:@"%@1", newString];
    }
}
Run Code Online (Sandbox Code Playgroud)

rma*_*ddy 5

您的calledFunction函数创建一个自动释放NSString,在当前自动释放池耗尽之前不会释放.

您的process函数calledFunction循环调用100,000次.在此循环的持续时间内,当前的自动释放池没有机会耗尽.process到达方法结束时,NSString创建的所有100,000个对象实例calledFunction仍在内存中.

使用大型循环时避免自动释放对象堆积的常见解决方案是添加一个额外的自动释放池,如下所示:

void process() {
    for (int i=0; i<targetCount; i++) {
        @autoreleasepool {
            calledFunction(i);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)