应用程序终止时泄漏

时间:2012-07-05 21:30:32

标签: objective-c ios c memory-management memory-leaks

我应该在应用程序终止时处理泄漏,还是让系统处理它们更有效?我认为系统无论如何都会回收所有的内存,所以不会有额外的努力来解决它的开销吗?

4 个答案:

答案 0 :(得分:3)

引用paxdiablo

  

我所知道的所有操作系统都将回收已分配的常规内存。这是因为分配通常来自进程私有地址空间,将在退出时回收。

据我所知,这也适用于iOS。

然而,Apple可能拒绝您的申请。单独的内存泄漏通常没有理由拒绝应用程序,但它们可能是导致存储桶溢出的丢弃。适当的内存管理是很好的做法,应该始终如一。

答案 1 :(得分:2)

当您的应用终止时,没有理由尝试释放所有内存。

这样做会浪费CPU周期。

当然,您可能需要一个“关闭”阶段,该阶段会持续某个状态,但您的代码也必须假设“关闭”代码路径可能无法运行。

当应用程序终止时,系统将回收应用程序分配的所有资源,无论其如何终止。

事实上,UIKit(iOS)和AppKit(OS X)在应用程序终止时都会占用大量快捷方式,这会导致在应用程序终止时仍然分配大量内存。这完全是出于回应的原因;当用户请求退出应用时,它应该很快退出。

(我真的不能想到现代的多任务,任务隔离,操作系统不能自动回收进程终止的资源。)

答案 2 :(得分:1)

所有应用程序(进程)都在自己的私有内存空间中运行。操作系统对此进行管理,并始终确切地知道已为该进程分配了什么“物理”内存。当进程退出时,它能够完全恢复所有已用内存。

因此,如果您的应用程序要退出,则不需要进行任何内存管理或清理(文件访问或网络连接等也是如此,但在这些情况下,它可能符合您的最佳利益)清理)。

但是,您的应用程序永远不应“泄漏”内存。

当您分配一块内存然后在正在运行的程序中丢失对它的所有引用时,就会出现泄漏。

单身不是泄漏,仪器不会将其标记为泄漏。

所以,如果你有这样的事情:

static NSString *aStaticString = nil;

+ (void)aFunction {
    aStaticString = [[NSString alloc] initWithString:@"aFunction"];
}

这不是泄漏。所以假设你还有另一个功能:

+ (void)anotherFunction {
    aStaticString = [[NSString alloc] initWithString:@"anotherFunction"];
}

现在,假设您正在使用ARC,调用这些函数不会导致泄漏。编译器/运行时知道管理NSString分配,并且当aStaticString变量更改时,释放旧内存。

所以考虑到这一点,你怎么得到泄漏?通常它将由于循环引用。例如:

+ (void)aBadFunction {
    NSMutableDictionary *aDict = [[NSMutableDictionary alloc] init];
    [aDict addObject:aDict forKey:@"aCircularReference"];
}

这里,创建(分配)aDict,然后向其添加对自身的引用。当函数返回时,内存会泄漏,因为程序不再对aDict变量有任何引用(如果再次调用该函数,将创建一个新的完全不同的aDict变量)。现在通常ARC会确保在函数退出时取消分配aDict,但在这种情况下它不能,因为在对象本身中有的引用

通常这样的循环引用更复杂,但原理是相同的。

答案 3 :(得分:0)

你应该总是释放记忆,但是,请参阅下面的评论:

之间有区别:

int main() {

    int* i = malloc(5);
    ... // do stuff here
    return 0; // i "leaked" here, not that serious, a lot of programmers will skip freeing `i` before return

}

int main() {

    int* i;
    for(int j = 0; j < 5000; j++)
        i = malloc(5); // you leaked 5 bytes 5000 times, very serious, DO NOT DO THIS
    // the 24KB here will most likely be reclaimed later, HOWEVER
    // what if j changes? what if you have more loops? you may run of memory, especially on an embedded device!
    ... // do stuff here
    return 0;

}

只需遵循一条规则:在处理正确的C内存管理(C编码约定)时,永远不要担心开销。

这样做:

int main() {

    int* i;
    for(int j = 0; j < 5000; j++) {
        i = malloc(5);
        ... // do stuff with i here
        free(i); // you are not leaking anything =D         
    }
    ... // do stuff here
    return 0;
}
相关问题