【问题标题】:leaks tool doesn't report memory leak on os x泄漏工具不报告 os x 上的内存泄漏
【发布时间】:2013-09-06 07:38:22
【问题描述】:

我正在尝试学习如何从命令行使用泄漏工具,这是我的代码,应该会在 NSString 上产生泄漏:

#import <Foundation/Foundation.h>
#import <unistd.h>

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

    pid_t pid = getpid();
    NSLog(@"pid: %d", pid);

    string = nil;
    [NSThread sleepForTimeInterval:20];

    return 0;
}

我了解到泄漏每 10 秒刷新一次(不确定这是否属实,但我将间隔设置为 20 秒)。

这应该会产生泄漏,因为它不在自动释放池中,而且我为了“安全”而使用-fno-objc-arc 编译。

我尝试多次运行泄漏[pid],但没有报告任何泄漏。我在这里做错了什么? 另外,我是一个命令行迷,我真的很想能够使用类似于 valgrind 的东西,它不能很好地支持 os x 10.8。为了使用泄漏工具,我必须在代码中设置睡眠,这很烦人。

有人可以在这里点亮一些灯吗?

【问题讨论】:

    标签: objective-c macos memory-leaks


    【解决方案1】:
    NSString *string = [[NSString alloc] init];
    

    返回一个空字符串的共享实例(多个调用返回同一个实例)。 Foundation 框架保留了对这个共享实例的引用,因此 没有内存泄漏

    对于其他不可变类(NSArrayNSDictionary)也可以观察到相同的行为。

    如果你用

    替换你的行
    NSMutableString *string = [[NSMutableString alloc] init];
    

    然后你会看到内存泄漏。

    【讨论】:

    • 我不应该忘记字符串池。您的解决方案有效。但是,如果我在程序退出之前摆脱 'string = nil',它就不起作用(这是有道理的,因为 string 仍然拥有所有权)。但在实践中,我不可能为我想要监控的所有对象设置 nil。有更好的解决方案吗?
    【解决方案2】:
    1. 如果您使用 ARC,则不会发生泄漏。
    2. 空字符串 ([[NSString alloc] init]) 绝对是共享/重用实例。系统必须保留对共享实例的引用,因此泄漏(正确)不会报告它。

    更好的测试是使用自定义对象。然后你就可以确定没有魔法。

    #if __has_feature(objc_arc)
    #error This leaks test only works when ARC is off
    #endif
    
    @interface Orphan : NSObject @end
    @implementation Orphan @end
    
    
    // in main, create an object without keeping a reference to it:
    [Orphan new];
    

    【讨论】:

    • 我不应该忘记字符串池。您的解决方案有效。但是,如果我在程序退出之前摆脱 'string = nil',它就不起作用(这是有道理的,因为 string 仍然拥有所有权)。但在实践中,我不可能为我想要监控的所有对象设置 nil。有更好的解决方案吗?
    • @bohanl 不,在使用 leaks 工具时不会。您可以在 ARC 中使用 __weak 引用,但这在实践中不起作用,因为引用很弱。
    • @bohanl 不过,有更好的工具可以调试此类问题。您正在搜索所谓的“废弃内存”(仍然存在指针的内存,但仍然不再需要该对象)。 Instruments 包含可用于执行“Heap Shot 分析”(现在称为生成分析)的“分配”工具。这是搜索废弃记忆的绝妙工具。
    猜你喜欢
    • 1970-01-01
    • 2020-09-17
    • 2011-01-21
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 2015-04-05
    相关资源
    最近更新 更多