我编写了一个非常简单的测试应用程序,试图帮助我正在处理的一个更大的项目。
简单地说,测试应用程序循环预定的次数,并在每次循环时将“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];
}
}
最佳答案
您的calledFunction
函数创建一个自动释放的 NSString
在当前自动释放池耗尽之前不会被释放。
您的process
函数调用calledFunction
循环100,000次。在此循环期间,当前自动释放池没有机会耗尽。到process
结束时方法到达后, NSString
的所有 100,000 个实例calledFunction
中创建的对象仍然在内存中。
使用大循环时避免累积自动释放对象的常见解决方案是添加额外的自动释放池,如下所示:
void process() {
for (int i=0; i<targetCount; i++) {
@autoreleasepool {
calledFunction(i);
}
}
}
关于Objective-C 重用 NSString 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37141175/