在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”工具来实时查看设备的统计信息。 开箱即用,包括查看可用内存,磁盘空间和日志以及修改日志级别的页面。 添加显示您想要的任何信息的自定义页面也很容易。
苹果提供的开发工具包括“工具”。 您可以使用它来监视分配和泄漏。 在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图像类,这是有效的 。