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

Hou*_*man 6 xcode memory-leaks ios ios7

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

在此输入图像描述

我切换到呼叫树.

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

在此输入图像描述

但它并没有真正给我任何线索.我怎么知道造成泄漏的原因?

在此输入图像描述

更新:

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

在此输入图像描述

  • 您在应用程序中执行的重现此泄漏的一些描述:

我们的应用程序在应用程序启动(前景)时与我们的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.
Run Code Online (Sandbox Code Playgroud)

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

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'
Run Code Online (Sandbox Code Playgroud)

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

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

  • 您正在运行的Xcode版本.

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

我希望这有帮助.谢谢

Rob*_*Rob 2

尽管泄漏中的红色尖峰看起来很危险,但泄漏的总内存为 1.06kb,这极不可能是问题的根源(甚至与问题无关)。

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

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

12 月 15 日 11:12:26 Robs-iPad myapp[2224] :收到内存警告。

但我在你的控制台转储中没有看到上述内容,所以这让我怀疑你是否真的收到了内存警告。

我可能建议在您的应用程序委托中插入显式日志记录:

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

    // free whatever caches or other temporary resources you can here
}
Run Code Online (Sandbox Code Playgroud)

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

- (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];
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

但让我们暂时假设该问题确实是内存警告的结果。这就引出了两个问题:首先,您首先要做什么来减轻内存警告(例如,使用来@autoreleasepool减轻高水位标记,如果不是绝对必要,则不要同时在内存中保存大量资源,使用而imageWithContentsOfFile不是imageNamed)?其次,您正在做什么来响应内存警告(例如,您是否正在清除缓存等)?

因此,如果您确实确认内存警告确实是问题的根源(并首先这样做),那么在同步过程中查看分配图可能会很有趣(并确认活动字节的峰值数量,如以及最终的活动字节数)。看看你问题中的分配图,它看起来并不算太糟糕(即没有剧烈波动),但是话又说回来,你还没有与我们分享“活动字节”的数量,所以很难说。

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


我最初的答案(如下)是对最初问题的回应,该问题仅仅是“似乎与我的代码不符的仪器显示的泄漏是什么”。我将其保留在这里以供参考:


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

您可能想分享:

  • 显示系统库的调用树;

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

  • 关于您在应用程序中为重现此泄漏所做的操作的一些描述;

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

  • 你正在运行什么 Xcode 版本。

坦率地说,鉴于 (a) 泄漏的大小可以忽略不计;(b) 没有迹象表明问题出在您的代码中;(c) iOS 框架确实存在超出您控制范围的泄漏这一事实。但如果您担心,请分享上述一些信息,我们也许可以提供进一步的观察。