iPhone应用程序使用了150MB内存,但仍未出现低内存警告!

4
我有一个问卷应用程序,基于导航栏,每次从nib中创建并推送我的tableviews。没有泄漏,在instruments的实时字节看起来大约是2-3 MB。
我在真实设备(越狱的IOS4 iPhone)上测试过,当我深入导航(大约200页推送)时,可以看到内存使用量增加到150 MB!当我导航回根时,它们都被释放了,但这不是一种奇怪的行为吗?(每个nib视图约为800 KB,其中没有大型数据或图像)
最奇怪的是,我在didreceivememorywarning和didunloadview方法中放置了一些警报,但仍然没有收到任何内存警报!
-为什么我从未收到任何内存警告和viewDidUnload,即使应用程序使用了150 MB及以上的内存? -应用程序可以正常工作,但这种内存使用情况对Apple store是否构成问题?

你尝试在非越狱的iPhone上运行你的应用了吗?此外,你应该在Edge iPhone或3G iPhone上尝试一下,以了解内存使用情况的真实情况。 - scalbatty
@Luzal 我的目标是ios4,越狱可能会有问题吗? - Spring
3个回答

16

发生了一些奇怪的事情。尝试使用以下代码检查操作系统版本以及应用程序使用的内存量。

-(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));
    }


}

你需要使用 #import "mach/mach.h"。

这将告诉你操作系统已经授予你的应用程序多少内存。因此,如果你看到的是一些奇怪的仪器行为,这将有所启示。


1
我在模拟器中尝试了这段代码,应用程序启动时的内存为28 Mb,并随着导航的使用而增加到60-70MB(每次推送增加300Kb),但我根本没有收到任何内存警告。 - Spring
1
模拟器的内存比设备多得多。在设备上试试看。 - fsaint
1
我在设备上尝试了一下,每次推送都会保留大约1MB的内存!我可以使用200MB的内存而没有任何低内存警告,但是当我打开其他应用程序来填充内存然后返回时,我看到它已经释放了大约50MB左右,但仍然没有迹象表明它触发了didreceivememoryWarning方法?这里发生了什么?为什么每个推送的视图都浪费1MB的内存? - Spring
1
每个推送的视图占用1Mb并不令人惊讶。当它们在导航堆栈中时,这些视图仍然存在于内存中。奇怪的是应用程序没有崩溃。通常我的问题是应用程序崩溃!而不是相反。干杯。 - fsaint
每次推送控制器时,我应该卸载视图吗?苹果商店对于巨大的内存使用有什么说法? - Spring
显示剩余3条评论

2

我只是在viewDidDisappear方法中添加了self.view=nil,它起作用了,我可以恢复回来,现在好多了。感谢Felz的帮助。


0

虽然这是一个老问题,但是为了补充fsaint的答案,如果有人仍然想知道如何使用它:

它可以放在任何您想要记录内存使用情况的地方,比如特定的视图控制器中。要记录整个应用程序,您可以将其放在AppDelegate.m文件中。在文件顶部:

#import <mach/mach.h>

将该方法粘贴到类的任何位置:

- (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 ) {
        long mb = info.resident_size / 1000000;
        NSLog(@"Memory in use (in Mbytes): %lu", (long)mb);
    } else {
        NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
    }
}

在 didFinishLaunchingWithOptions: 方法中加入一个计时器来调用此方法。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    (...)
    [NSTimer scheduledTimerWithTimeInterval: 2.0
                                     target: self
                                   selector: @selector(report_memory)
                                   userInfo: nil
                                    repeats: YES];
}

运行应用程序并观察内存使用的日志。

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