问题描述
我一直在开发一个非常图形密集的iPad应用程序。我已经能够在iPad 2上挤出相当多的性能,但是新iPad的@ 2x显卡在内存部门打包了很多。使用仪器中的活动监视器我能够看到我的应用程序的大小迅速增加到300MB-400MB范围,但我没有收到任何低内存通知。我使用 UINavigationController
来管理我的视图,因此进入堆栈会对内存产生累积影响,最终会终止。我没有在iPad 2上遇到这个问题,因为我收到了预期的低内存通知。我的应用程序已编码为尽可能清理并在该设备上表现良好。
I have been developing an application for iPad that is very graphically intensive. I have been able to squeeze quite a bit of performance out already on the iPad 2, but the @2x graphics for the new iPad are packing quite the punch in the memory department. Using the Activity Monitor in Instruments I am able to see the size of my application mushrooming into the 300MB-400MB range but I do not receive any low memory notifications. I am using a UINavigationController
to manage my views, so getting down into the stack has a cumulative effect on memory that ends in its eventual termination. I do not experience this problem on the iPad 2, where I receive low memory notifications as expected. My app has been coded to clean up as much as possible and performs very well on that device.
我已阅读了许多类似的问题:
I have read a number of similar questions asked:
IOS app killed for Low Memory but no Memory Warning received
iPhone app uses 150 MB memory and still no low memory warning!
这些建议似乎都没有帮助。
None of the suggestions seem to help.
我已插入代码以强制发送低内存通知:
I have inserted code to force a low-memory notification to be sent:
[[UIApplication sharedApplication] _performMemoryWarning];
这会导致非活动视图按预期卸载并将内存消耗恢复正常。这使用私有API并且是黑客,因此出于实际原因不是解决方案。 如何让我的设备正确响应低内存条件并让我的应用知道它需要清理?
This does cause the inactive views to unload as expected and returns memory consumption to normal. This uses a private API and is hack, so for practical reasons is not a solution. How do I get my device to properly respond to low memory conditions and let my app know that it needs to clean up??
推荐答案
此问题已在iOS 5.1.1中修复。对于那些使用5.1的用户,我已经实现了自己的内存监视程序并发出类似于发出实际内存警告时使用的通知。
This problem was fixed in iOS 5.1.1. For those users who are on 5.1, I have implemented my own memory watchdog and sending out a notification similar to the one used when a real memory warning is issued.
我首先在 UIApplication
上创建了一个类别。这会发布一条通知, UIImage
会监听(或其后备缓存)以卸载缓存的图像。
I first created a category on UIApplication
. This posts a notification that UIImage
listens for (or whatever its backing cache is) to unload cached images.
.h
@interface UIApplication (ForceLowMemory)
+ (void) forceUnload;
@end
.m
#import "UIApplication+ForceLowMemory.h"
@implementation UIApplication (ForceLowMemory)
+ (void)forceUnload {
[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidReceiveMemoryWarningNotification
object:[UIApplication sharedApplication]];
}
@end
接下来,我创建了一个内存经理看门狗如下:
Next, I created a memory manager watchdog like the following:
.h
@interface ELMemoryManager : NSObject
- (void)startObserving;
- (void)stopObserving;
+ (ELMemoryManager*) sharedInstance;
@end
.m
#import "ELMemoryManager.h"
#import "UIApplication+ForceLowMemory.h"
#import <mach/mach.h>
@interface ELMemoryManager()
@property (nonatomic, retain) NSTimer *timer;
uint report_memory(void);
@end
#define MAX_MEM_SIZE 475000000
@implementation ELMemoryManager
@synthesize timer = timer_;
static ELMemoryManager* manager;
#pragma mark - Singleton
+ (void) initialize {
if (manager == nil) {
manager = [[ELMemoryManager alloc] init];
}
}
+ (ELMemoryManager*) sharedInstance {
return manager;
}
#pragma mark - Instance Methods
uint report_memory(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);
if( kerr == KERN_SUCCESS ) {
return info.resident_size;
} else {
return 0;
}
}
- (void)startObserving {
if (!self.timer) {
NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:@selector(checkMemory:) userInfo:nil repeats:YES];
self.timer = timer;
}
[self.timer fire];
}
- (void)stopObserving {
[self.timer invalidate];
self.timer = nil;
}
- (void)checkMemory:(id)sender {
uint size = report_memory();
if (size > MAX_MEM_SIZE) {
NSLog(@"we've busted the upper limit!!!");
[UIApplication forceUnload];
}
}
#pragma mark - Memory Management
- (void)dealloc {
[self.timer invalidate];
[timer_ release];
[super dealloc];
}
@end
这篇关于新iPad:低内存警告没有出现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!