Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 理解';泄漏';用于查找内存泄漏的命令行实用程序_Iphone_Objective C_Cocoa_Cocoa Touch_Memory Leaks - Fatal编程技术网

Iphone 理解';泄漏';用于查找内存泄漏的命令行实用程序

Iphone 理解';泄漏';用于查找内存泄漏的命令行实用程序,iphone,objective-c,cocoa,cocoa-touch,memory-leaks,Iphone,Objective C,Cocoa,Cocoa Touch,Memory Leaks,我正在追踪我的iPhone程序中一些难以发现的内存泄漏。我正在一个应用程序上运行一个快速测试,该应用程序泄漏了一个NSString对象,故意使用以下错误代码: -(void)applicationDidFinishLaunching:(NSNotification *)notification; { NSMutableString *test = [[NSMutableString alloc] init]; [test appendString:@"Testing 1"];

我正在追踪我的iPhone程序中一些难以发现的内存泄漏。我正在一个应用程序上运行一个快速测试,该应用程序泄漏了一个NSString对象,故意使用以下错误代码:

-(void)applicationDidFinishLaunching:(NSNotification *)notification;
{
    NSMutableString *test = [[NSMutableString alloc] init];
    [test appendString:@"Testing 1"];
    [test appendString:@"\nTesting 2"];
    NSLog(@"%@", test);

    // Uncomment the following line to release the
    // string and clean up your leak.
    // [test release], test = nil;
}
在应用程序的进程ID上运行泄漏后,我得出以下结论:

sf$ leaks 3951
Process 3951: 9988 nodes malloced for 1260 KB
Process 3951: 3 leaks for 128 total leaked bytes.
Leak: 0x163b50  size=64 instance of 'NSCFDictionary', type ObjC, implemented in Foundation  
    0xa07e0720 0x01001080 0x0000000a 0x00000010      .~.............
    0x0000000a 0x0000000c 0x0000000b 0x00000000     ................
    0x00000000 0x00000015 0xa1b1c1d3 0x00163b90     .............;..
    0x00163bd0 0x00000000 0x00000000 0x00000000     .;..............
Leak: 0x178190  size=32 string 'Testing 1
Testing 2'
Leak: 0x178210  size=32 instance of 'NSCFString', type ObjC, implemented in CoreFoundation  
    0xa02e24a0 0x010007ad 0x00178190 0x00000013     .$..............
    0x00000020 0x00000200 0x00000000 0x00000000      ...............
现在,我们都知道漏洞在哪里了。至少对我来说,这不是这个练习的重点。我试图认识到如何理解这个输出。有人告诉我有3处漏洞

它们是位于内存地址0x163b50、0x178190、0x178210处的对象。根据“泄密”的说法,它们是在苹果框架中实现的,而不是我的代码。在下面这样一个简单的例子中,查找泄漏并不困难。然而,在一个有500K行代码的应用程序中,我发现这里泄漏的输出是无用的

我做错了什么?我如何理解这个输出来帮助我找到我为清理内存泄漏而编写的代码中的罪魁祸首

请注意,此线程不应提倡使用仪器或叮当静态分析仪。我已经清除了Clang Static Analyzer向我报告的所有内存泄漏。仪器太臃肿,对我来说没有信息。我收到了大量关于泄漏的报告,没有一个堆栈跟踪显示返回到我自己的代码——尽管我确信泄漏确实存在于我的代码中。我想知道如何在这里使用cmd line leaks工具

谢谢大家

编辑:即使在取消对行的注释以清除泄漏之后,“泄漏”实用程序的抱怨甚至比发生泄漏时还要多。基金会/可可豆从这样一个微不足道的例子中泄漏了那么多吗?这是在取消注释上述测试字符串的版本后发生的:

sf$ leaks 4383
Process 4383: 9890 nodes malloced for 1255 KB
Process 4383: 7 leaks for 560 total leaked bytes.
Leak: 0x163920  size=176    instance of 'NSPathStore2', type ObjC, implemented in Foundation    
    0xa07e2ae0 0x04f00000 0x0055002f 0x00650073     .*~...../.U.s.e.
    0x00730072 0x0073002f 0x002f0066 0x0069004c     r.s./.s.f./.L.i.
    0x00720062 0x00720061 0x002f0079 0x00700041     b.r.a.r.y./.A.p.
    0x006c0070 0x00630069 0x00740061 0x006f0069     p.l.i.c.a.t.i.o.
    0x0020006e 0x00750053 0x00700070 0x0072006f     n. .S.u.p.p.o.r.
    0x002f0074 0x00490053 0x0042004d 0x002f004c     t./.S.I.M.B.L./.
    0x006c0050 0x00670075 0x006e0069 0x002f0073     P.l.u.g.i.n.s./.
    0x00650054 0x006d0072 0x006e0069 0x006c0061     T.e.r.m.i.n.a.l.
    ...
Leak: 0x163350  size=160    instance of 'NSPathStore2', type ObjC, implemented in Foundation    
    0xa07e2ae0 0x04a00000 0x0055002f 0x00650073     .*~...../.U.s.e.
    0x00730072 0x0073002f 0x002f0066 0x0069004c     r.s./.s.f./.L.i.
    0x00720062 0x00720061 0x002f0079 0x00700041     b.r.a.r.y./.A.p.
    0x006c0070 0x00630069 0x00740061 0x006f0069     p.l.i.c.a.t.i.o.
    0x0020006e 0x00750053 0x00700070 0x0072006f     n. .S.u.p.p.o.r.
    0x002f0074 0x00490053 0x0042004d 0x002f004c     t./.S.I.M.B.L./.
    0x006c0050 0x00670075 0x006e0069 0x002f0073     P.l.u.g.i.n.s./.
    0x00650044 0x0069006c 0x00690063 0x0075006f     D.e.l.i.c.i.o.u.
    ...
Leak: 0x1635a0  size=64 instance of 'NSCFDictionary', type ObjC, implemented in Foundation  
    0xa07e0720 0x01001080 0x0000000a 0x00000010      .~.............
    0x0000000a 0x0000000c 0x0000000b 0x00000000     ................
    0x00000000 0x00000015 0xa1b1c1d3 0x001635e0     .............5..
    0x00163620 0x00000000 0x00000000 0x00000000      6..............
Leak: 0x163620  size=64 
    0xa02ed360 0x00160ee0 0x00163700 0xa02efc00     `........7......
    0x00000000 0x00000000 0x00163680 0x00000000     .........6......
    0x00000000 0x00000000 0x00163660 0xa02ed440     ........`6..@...
    0xa02ec1a0 0xa02f0420 0x00000000 0x00163660     .... ./.....`6..
Leak: 0x163680  size=48 instance of 'NSCFString', type ObjC, implemented in CoreFoundation  
    0xa02e24a0 0x0100078c 0x6d6f6323 0x6c65642e     .$......#com.del
    0x6f696369 0x61737375 0x69726166 0x6c65442e     icioussafari.Del
    0x6f696369 0x61537375 0x69726166 0x00000000     iciousSafari....
Leak: 0x163660  size=32 instance of 'NSCFString', type ObjC, implemented in CoreFoundation  
    0xa02e24a0 0x0200078c 0x6c65440f 0x6f696369     .$.......Delicio
    0x61537375 0x69726166 0x00000000 0x00000000     usSafari........
Leak: 0x160ee0  size=16 instance of 'NSCFString', type ObjC, implemented in CoreFoundation  
    0xa02e24a0 0x0100078c 0x362e3103 0x00000000     .$.......1.6....

对于本例,leaks报告3次泄漏,总共128字节。解释如下:

1) 您正在泄漏一个NSMutableString,该字符串似乎在内部实现为NSCFDictionary,总共64字节

2) 您正在泄漏测试1,总共32个字节

3) 您正在泄漏\n测试2总共32个字节

这应该是因为如果不释放NSMutableString,则属于NSCFDictionary数据结构的所有对象(在本例中为字符串)都不会被释放:每次使用appendString方法时都会保留这些对象。释放NSMutableString时,NSCFDictionary中的所有对象以及NSCFDictionary本身都会自动释放

从Apple文档()中:

如果Cocoa对象在没有自动释放池的情况下自动释放,Xcode会向控制台发送一条消息,警告您该对象正在泄漏。即使您没有编写Cocoa应用程序,也可能会看到相同类型的控制台警告。许多可可类的实施是基于核心基础类型。如果您的应用程序使用核心基础,则可能由于调用该框架而发生泄漏。


要查找这种类型的内存泄漏,请使用调试器在_NSAutoreleaseNoPool函数上设置断点。这个函数在NoundDebug .h中在基础框架中声明。当调试器到达该函数时,您应该能够查看堆栈爬网并查看是哪段代码导致了泄漏。

我认为您在泄漏中看到这一点的原因是因为
appendString
在内部使用了
自动释放。在下一个“事件”之前不会丢弃自动释放池。基本上,我认为这个样本太简单了,无法准确地显示发生了什么

我在这里可能有点离谱,但我会尝试将您的代码包装到自动释放池中,看看有什么变化

-(void)applicationDidFinishLaunching:(NSNotification *)notification;
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSMutableString *test = [[NSMutableString alloc] init];
    [test appendString:@"Testing 1"];
    [test appendString:@"\nTesting 2"];
    NSLog(@"%@", test);
    [test release], test = nil;
    [pool release] // this should drain the autorelease pool
}

您显示的输出中没有堆栈跟踪。您看到的地址是对象自己的地址,而不是函数指针,标点符号旁边的十六进制数只是数据的十六进制转储

要找出对象的分配来源,请在leaks的环境中设置MallocStackLogging:

% MallocStackLogging=1 leaks …
您可能还希望使用-nocontent选项,这将抑制十六进制转储。但是,不要总是使用这个:有时候十六进制转储包含有价值的线索

此外,泄漏不一定告诉你你有三个泄漏;准确地说,它告诉你有三个泄漏的物体。您显示的故意泄漏只会产生一个泄漏对象,但不同的泄漏(例如在循环中或经常调用的方法中)可能会泄漏多个对象


编辑:顺便说一句,其中一些泄漏来自SIMBL或一个或多个SIMBL插件。在查找泄漏之前,关闭SIMBL和任何其他输入管理器黑客。记住,代码在您的流程中运行;此外,leaks不关心是谁的代码分配或泄漏了内存,只关心内存是否泄漏,因此无论是谁分配或泄漏了内存,它都会显示泄漏的对象。

谢谢Peter。我不知道SIMBL是什么,但我会查一下。这是mac应用程序还是iphone应用程序?你能在iphone上使用mac的二进制文件吗?