iOS:如何识别Xcode仪器的泄漏?

时间:2013-12-15 13:05:28

标签: ios xcode memory-leaks ios7

我利用分析器来查找内存泄漏并遇到了这个问题:

enter image description here

我切换到呼叫树。

所以我可以点击它以了解更多信息:

enter image description here

但它并没有真正给我任何线索。我怎么知道导致泄漏的原因?

enter image description here

更新

  • 显示系统库的调用树在上面更新。
  • 有关泄露对象的信息:

enter image description here

  • 您在应用中为重现此泄漏所做的一些描述:

我们的应用程序在应用程序启动(前景)时与我们的REST-API同步。这总是在我的iOS 7 / iPhone 4S上运行。但是另一个开发者拥有iOS7 / iPhone 5并且很少运行它不同步的问题。经过10天观察并将NSLogs放到任何地方后,我们昨晚发现了这一点:

Dec 15 03:18:58  appname[4801] <Warning>: A gateway to the host server is working via WWAN.
Dec 15 03:18:58  appname[4801] <Warning>: Syncing...
Dec 15 03:18:58  appname[4801] <Warning>: Eventname to be fired: f11-reachability
Dec 15 03:18:58  appname[4801] <Warning>: Sync event IOS_REACHABILITY reached.
Dec 15 03:18:58  appname[4801] <Warning>: Sync: IOS_SYNC_WITH_SERVER is true
Dec 15 03:18:58  appname[4801] <Warning>: Animating indicator...
Dec 15 03:18:58  appname[4801] <Warning>: Getting last timestamp: 1387003344.407783 then calling syncWithServerWithDate
Dec 15 03:19:27  com.apple.launchd[1] <Notice>: (UIKitApplication:com.apple.mobilecal[0x45fb]) Exited: Killed: 9
Dec 15 03:19:27  com.apple.launchd[1] <Notice>: (com.apple.afcd) Idle-exit job was jettisoned. Will bypass throttle interval for next on-demand launch.
Dec 15 03:19:27  com.apple.launchd[1] <Error>: (com.apple.afcd) assertion failed: 11B554a: launchd + 35697 [3C91C465-EFA6-32C7-A677-DD0B5FDEE0DC]: 0x9
Dec 15 03:19:27  com.apple.launchd[1] <Notice>: (com.apple.absd) Idle-exit job was jettisoned. Will bypass throttle interval for next on-demand launch.

第三次尝试同步(按下主页按钮并回到前台)给了我们这个,这表明内存不足:

Dec 15 03:25:18 C1 appname[4801] <Warning>: Getting last timestamp: 1387003344.407783 then calling syncWithServerWithDate
Dec 15 03:25:29 C1 profiled[6244] <Notice>: (Note ) profiled: Service stopping.
Dec 15 03:25:40 C1 crash_mover[6248] <Notice>: (Warn ) <crash_mover.m mv_recursive:98> Moving './LowMemory-2013-12-14-160222.plist' -> '/var/mobile/Library/Logs/CrashReporter/LowMemory-2013-12-14-160222.plist'

所以我想我给了探查器一个去看看我是否找到了什么。

为了重现它,我已启动应用程序,转到主屏幕,然后按下Simulate a Low Memory,然后单击应用程序返回到前台。这是我得到红色尖峰的地方。

  • 您正在运行的Xcode版本。

Xcode 5.02。 iPhone 4S(OK)上的iOS 7.04,iPhone 5(罕见边缘情况)

我希望这会有所帮助。谢谢

1 个答案:

答案 0 :(得分:2)

随着泄漏中的红色峰值出现威胁,泄漏的总内存为1.06kb,这极不可能是您的问题的来源(甚至没有相关)。

就你的应用程序导致其他应用程序被抛弃而言,这本身并不是问题,我不会那么担心(但是,要成为一个好公民,你真的应该尽量减少这个) 。更直接的功能问题是您的应用程序无法同步的原因以及这是否真的是应用程序本身内存警告的结果(或更准确地说,是应用程序无法充分释放资源以响应内存警告,结果在后续的内存分配中失败)。

在我看来,第一个问题是你是否真的在你的应用程序中获得内存警告。一般来说,如果应用程序确实有内存警告,我会在控制台中看到如下内容:

Dec 15 11:12:26 Robs-iPad myapp[2224] : Received memory warning.

但是我没有在你的控制台转储中看到上述内容,因此我想知道你是否真的收到了内存警告。

我可能会建议在您的应用代理中插入显式记录:

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
    NSLog(@"%s", __FUNCTION__);

    // free whatever caches or other temporary resources you can here
}

或在视图控制器中进行特殊处理:

- (void)didReceiveMemoryWarning
{
    NSLog(@"%s", __FUNCTION__);

    [super didReceiveMemoryWarning];

    // do whatever you want to free resources here

    [[[UIAlertView alloc] initWithTitle:nil
                                message:@"didReceiveMemoryWarning"
                               delegate:nil
                      cancelButtonTitle:@"OK"
                      otherButtonTitles:nil] show];
}

这会导致在我的控制台中看到以下内容:

Dec 15 11:12:26 Robs-iPad myapp[2224] : -[AppDelegate applicationDidReceiveMemoryWarning:]
Dec 15 11:12:26 Robs-iPad myapp[2224] : -[ViewController didReceiveMemoryWarning]

但关键目标是确认您是否真的收到了内存警告,以及这是否真的与您的应用无法同步相关。

但让我们假设问题实际上是内存警告的结果。这就引出了两个问题:首先,你在做什么来减轻内存警告(例如使用@autoreleasepool来缓解高水位标记,如果不是绝对的话,不会同时在内存中保留大量资源必要的,使用imageWithContentsOfFile而不是imageNamed)?第二,你在回应内存警告时做了什么(例如,你是否清除了缓存等)?

因此,如果您确实确认内存警告确实是问题的根源(并且首先执行此操作),那么在同步过程中查看您的分配图可能会很有趣(并确认实时峰值数量)字节,以及最终的活字节数)。看看你问题中的分配图,它看起来并不太糟糕(即没有狂野的波动),但是,再一次,你还没有与我们分享“活字节”的数量,所以很难说。

但是当你模拟内存警告时,我绝对不会担心1kb的泄漏。这比你需要担心的任何严重症状更令人烦恼。留意泄漏,但要注意(a)大量泄漏; (b)代码中的那些,而不是框架中的那些。


我在下面的原始答案是对最初的问题的回答,这个问题仅仅是“这些泄漏是由那些似乎与我的代码不相符的工具所显示的”。我会把它留在这里供参考:


这可能表明泄漏不在您的代码中,而是在系统框架中(您已隐藏)。

您可能想要分享:

  • 显示系统库的调用树;

  • 有关泄漏对象的信息(所以,不仅仅是“调用树”,而是“泄漏”列表);

  • 您在应用中执行的操作的一些描述,以重现此泄漏;

  • 您看到哪个iOS版本会出现这个问题,哪些版本不存在(框架本身并非没有泄漏,但它因iOS目标而异);和

  • 您正在运行的Xcode版本。

坦率地说,你可能最终无视这个问题,因为(a)漏洞的大小可以忽略不计; (b)没有迹象表明问题存在于您的代码中; (c)iOS框架确实存在您无法控制的泄漏。但如果你担心,请分享一些上述信息,我们或许可以提供进一步的观察。