iOS低内存崩溃,但内存使用非常低

36

这个问题已经困扰我很长时间了。我的应用程序运行时大约占据了2.74MB的内存,这没有问题。但是当它创建一个UIWebView时,内存占用会上升到大约5.87MB,然后应用程序就崩溃了。这些值是在我的第一代iPad上运行时,在Instruments中显示的实时字节数。

我找不到任何崩溃日志。以下是控制台中的内容:

MyApp[1205] <Warning>: Received memory warning. Level=1
MyApp[1205] <Warning>: applicationDidReceiveMemoryWarning
SpringBoard[30] <Warning>: Received memory warning. Level=1
MobileMail[1199] <Warning>: Received memory warning. Level=1
configd[26] <Notice>: jetsam: kernel memory event (95), free: 428, active: 1853, inactive: 1011, purgeable: 338, wired: 15122
configd[26] <Notice>: jetsam: kernel termination snapshot being created
com.apple.launchd[1] <Notice>: (UIKitApplication:com.apple.mobilemail[0x8966]) Exited: Killed: 9
com.apple.launchd[1] <Notice>: (UIKitApplication:com.MyApp.MyApp[0xdd4f]) Exited: Killed: 9
SpringBoard[30] <Warning>: Application 'Mail' exited abnormally with signal 9: Killed: 9
kernel[0] <Debug>: launchd[1207] Builtin profile: MobileMail (sandbox)
SpringBoard[30] <Warning>: Application 'MyApp' exited abnormally with signal 9: Killed: 9
configd[26] <Debug>: CaptiveNetworkSupport:UIAllowedNotifyCallback:70 uiallowed: false
ReportCrash[1206] <Error>: libMobileGestalt loadBasebandMobileEquipmentInfo: CommCenter error: 1:45
ReportCrash[1206] <Error>: libMobileGestalt copyInternationalMobileEquipmentIdentity: Could not get mobile equipment info dictionary
ReportCrash[1206] <Error>: Saved crashreport to /Library/Logs/CrashReporter/LowMemory-2011-05-12-160645.plist using uid: 0 gid: 0, synthetic_euid: 0 egid: 0

我已经删除了所有对imageNamed的调用,并将自动释放的内容更改为alloc/release。但我无法弄清楚为什么会发生这种情况,这让我疯掉了。

感谢任何帮助!


看起来你的应用程序并没有崩溃,而是被终止以释放内存。这发生时它是否在前台运行? - Tony
是的,它一直在前台。应用程序打开时使用2.74MB,然后我点击打开UIWebView,使用量增加到5.87MB,几秒钟后就被杀死了。这发生在加载任何稍微复杂的网页时。 - Max
1
我认为5.87MB并不是什么大问题。我猜测一个视图控制器被卸载了,这导致了其他问题。尝试使用NSLogs或调试您的视图控制器中的viewDidUnload。 - ax123man
实际上并没有使用任何视图控制器。它基本上只是一个带有UITableView、UIView和UIWebView的UIView。 - Max
@Hanuman 我认为那个错误与此无关,看起来那是崩溃报告程序试图收集设备的所有数据,而不是获取仅适用于iPhone的东西。 - Max
显示剩余6条评论
3个回答

51

你很可能使用了比你想象中更多的内存。

要查看应用程序真正使用的内存,需要进行以下操作,但只要做几次,就会记住。

  1. 使用分配性能工具运行。
  2. 在“分配”下面点击VM Tracker的“行”(见截图)
  3. 点击“自动快照”

然后您将看到您的脏内存(在我的屏幕截图中目前为20.34MB)。

这应该会给您一个更清晰的图片,说明为什么您的应用程序会退出。您可能有一些大型泄漏正在发生。

祝好运!

此屏幕截图将有所帮助


谢谢你的提示,保罗!脏内存占用34MB,虚拟内存占用67MB。当我扩展它时,我看到几行Core Animation类型占据了相当大的比例,但没有其他熟悉的东西。有什么建议或想法可以进一步解决这个问题吗? - Max
不了解您的应用程序工作方式,很难说,但一个好的起点是查看哪些资源被保留的时间可能比您需要的时间长。在视图控制器的内存管理方法中放置一些日志语句,以查看它们何时被卸载和/或释放。您可能会发现有些资源挂在那里的时间比您认为的要长得多。然后您可以找出原因所在。 - Paul Bruneau
例如,我在上面截图的应用程序是一款图片书应用程序,其中包含一个滚动视图,其中包含单独的页面。它只有18页,可以全部保留在内存中。但我仍然有代码,当它们到达“页面缓存队列”的末尾时,会卸载页面(只是一个数组)。如果查看了某个页面,则该页面将移到数组的顶部。如果数组中有超过x页,则删除第x + 1页并释放内存。 - Paul Bruneau

22

我有两件事情要补充,可能会有所帮助:

  1. 如先前 答案 所述,UIImage 的位图不计入 Memory Leaks 告诉你的应用程序使用的内存量!因此,您可能有很多使用大量内存但在总内存中没有显示的 UIImage。我的建议是使用 Allocations 检查在应用程序运行时创建和销毁的 UIImage 对象数量。
  2. 此答案 中提到,使用以下代码

    -(void) report_memory {
        struct task_basic_info info;
        mach_msg_type_number_t size = sizeof(info);
        kern_return_t kerr = task_info(mach_task_self(),
                                       TASK_BASIC_INFO,
                                       (task_info_t)&info,
                                       &size);
        if( kerr == KERN_SUCCESS ) {
            NSLog(@"Memory in use (in bytes): %u", info.resident_size);
        } else {
            NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
        }
    }
    

想要查看操作系统为您的应用分配的内存量。这是您的应用程序使用的内存更准确的数字。(您需要导入 "mach/mach.h")

干杯!


-5
如果您快速按两次菜单按钮,您将看到应用程序,然后点击所有应用程序的x,再打开您需要的应用程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接