在iOS中观看内存使用情况

有什么办法可以找出iOS中有多less内存? 我知道当可用内存变低时,系统会传递低内存警告。 然而,我的应用程序有一些点,一个线程将执行一个复杂的任务,有时这个任务消耗足够的内存,它只是由操作系统终止(我的应用程序可以从互联网上下载图片,我缩小到一个小大小…如果用户下载一个非常大的图像,我的应用程序耗尽内存,只是“poof”)。

让App自发终止显然是一个糟糕的用户体验。

有没有什么方法可以在我即将耗尽内存的时候find解决办法呢?

我想我可以把任务放在一个单独的线程上,也许系统会给主线程发送一个低内存警告,但这看起来很复杂,甚至不能保证工作。

谢谢! 罗恩

在使用XCodetesting和debugging你的应用程序时,你可以使用这个logMemUsage()函数来NSLog使用/可用空间,并观察testing应用程序时的情况。 该functionlogging使用> 100kb的任何变化。 它输出到这样的debugging日志(在模拟器上的可用空间是巨大的):

 2011-11-02 21:55:58.928 hello[971:207] Memory used 21884.9 (+21885), free 1838366.8 kb 2011-11-02 21:55:59.936 hello[971:207] Memory used 28512.3 (+6627), free 1830809.6 kb 2011-11-02 21:56:01.936 hello[971:207] Memory used 28803.1 ( +291), free 1830129.6 kb 2011-11-02 21:56:02.936 hello[971:207] Memory used 29712.4 ( +909), free 1830142.0 kb 

您决定在您的应用程序中调用logMemUsage的位置。 我碰巧有一个函数,每秒由计时器调用,所以我把它放在那里。 我build议围绕这些使用#ifdef ,所以这段代码只包含在Debug版本中。

 #import "mach/mach.h" vm_size_t usedMemory(void) { 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); return (kerr == KERN_SUCCESS) ? info.resident_size : 0; // size in bytes } vm_size_t freeMemory(void) { mach_port_t host_port = mach_host_self(); mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); vm_size_t pagesize; vm_statistics_data_t vm_stat; host_page_size(host_port, &pagesize); (void) host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size); return vm_stat.free_count * pagesize; } void logMemUsage(void) { // compute memory usage and log if different by >= 100k static long prevMemUsage = 0; long curMemUsage = usedMemory(); long memUsageDiff = curMemUsage - prevMemUsage; if (memUsageDiff > 100000 || memUsageDiff < -100000) { prevMemUsage = curMemUsage; NSLog(@"Memory used %7.1f (%+5.0f), free %7.1f kb", curMemUsage/1000.0f, memUsageDiff/1000.0f, freeMemory()/1000.0f); } } 

其实每个视图控制器都有- (void)didReceiveMemoryWarning函数。

 - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } 

正如评论所build议的那样,您可以在评论下释放未使用的数据。 另一方面,注释掉[super didReceiveMemoryWarning]; 抑制内存警告和自动释放对象。

首先你的问题的标题是如何看iOS中的内存使用情况。有一个工具叫做仪器附带的Xcode,它可以用来跟踪内存分配,泄漏,CPU使用情况和其他东西..查看苹果的文档就此主题而言..

  • 现在看到你的应用程序的实时内存使用情况,你可以使用仪器中的分配器工具
  • 要识别内存泄漏,您可以使用仪器中的泄漏工具。

在WWDC 2010中还有一个关于如何使用仪器分析记忆的video 。

我build议查看Nimbus的“Overview”工具来实时查看设备的统计信息。 开箱即用,包括查看可用内存,磁盘空间和日志以及修改日志级别的页面。 添加显示您想要的任何信息的自定义页面也很容易。

http://latest.docs.nimbuskit.info/NimbusOverview.html

Nimbus'概述工具

苹果提供的开发工具包括“工具”。 您可以使用它来监视分配和泄漏。 在Xcode中,如果你长时间点击Runbutton,你会看到一个叫“Profile”的选项。 这将自动打开乐器,并允许您select一个configuration文件来监视您的应用程序。

我喜欢免费的代码。 谢谢你的程序,非常有用。 我开始分享回来的时间。 我为了自己的用例反对或者科学化了它。

 #import "mach/mach.h" #import "memusage.h" @implementation memusage static long prevMemUsage = 0; static long curMemUsage = 0; static long memUsageDiff = 0; static long curFreeMem = 0; -(vm_size_t) freeMemory { mach_port_t host_port = mach_host_self(); mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); vm_size_t pagesize; vm_statistics_data_t vm_stat; host_page_size(host_port, &pagesize); (void) host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size); return vm_stat.free_count * pagesize; } -(vm_size_t) usedMemory { 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); return (kerr == KERN_SUCCESS) ? info.resident_size : 0; // size in bytes } -(void) captureMemUsage { prevMemUsage = curMemUsage; curMemUsage = [self usedMemory]; memUsageDiff = curMemUsage - prevMemUsage; curFreeMem = [self freeMemory]; } -(NSString*) captureMemUsageGetString{ return [self captureMemUsageGetString: @"Memory used %7.1f (%+5.0f), free %7.1f kb"]; } -(NSString*) captureMemUsageGetString:(NSString*) formatstring { [self captureMemUsage]; return [NSString stringWithFormat:formatstring,curMemUsage/1000.0f, memUsageDiff/1000.0f, curFreeMem/1000.0f]; } @end 

听起来就像你可以使用一个精心devise的库来获取网页图像的任务。 Nimbus有一个networking图像类,这是有效的 。