Reputation: 869
I have a retain/release project that has a simple algorithm. I start out w/ a 100000 objects mutable array and every 5 seconds interval I remove 1000 objects at the beginning and add 1000 objects at the end. In theory my memory footprint should stay the same after a lil delay, however it consistently rises until it caps out at a certain amount. But removing all its objects with "[array removeAllObjects]" and releasing the array doesn't reclaim all the memory back, just a portion. I am running in release scheme, with no debugger, and using the activity monitor to track memory usage.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
array = [[NSMutableArray alloc] init];
for(int i = 0; i<100000; i++){
NSURL *url = [NSURL URLWithString:@"http://www.apple.com"];
[array addObject:url];
}
self.t = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(addAndRemove:) userInfo:nil repeats:YES];
}
-(IBAction)addAndRemove:(id)sender{
[array removeObjectsInRange:NSMakeRange(0, 1000)];
for(int i = 0; i<1000; i++){
NSURL *url = [NSURL URLWithString:@"http://www.apple.com"];
[array addObject:url];
}
}
-(IBAction)clear:(id)sender {
[array removeAllObjects];
[array release];
[t invalidate];
t = nil;
}
Upvotes: 0
Views: 366
Reputation: 90601
Monitoring your memory usage with Activity Monitor is pretty unreliable. First, which memory field are you watching (Virtual Private Memory, Real Private Memory, Real Shared Memory, or Real Memory)?
Second, when your code makes an allocation request, that typically goes, directly or indirectly, to the malloc routines. The malloc routines try to satisfy your request from the memory that it already has. If it can't then it requests more from the system. When you free memory, it goes back to malloc. Malloc does not necessarily return it to the system. It may keep it to more quickly satisfy future requests. So, you may not see your process's memory usage go down, at least not all the way, even if your program is releasing everything it allocated.
The proper way to check that your program is managing memory correctly is to use Instruments with the Leaks and Allocations tools.
Upvotes: 3
Reputation: 41005
When you create your NSURL using
NSURL *url = [NSURL URLWithString:@"http://www.apple.com"];
You are creating an Autoreleased object. Autoreleased objects get stored in the autorelease pool and are only destroyed when that pool is emptied. The main pool is flushed every 60th of a second when the main run loop fires, so maybe your objects are being released later than you expect them to be.
Try wrapping your for loops in an @autoreleasepool { } block so that any autoreleased objects created inside the loop are flushed immediately, or alternatively create your NSURL using alloc/init so that it's not autoreleased, e.g.
NSURL *url = [[NSURL alloc] initWithString:@"http://www.apple.com"];
Then see if that changes your memory usage.
Upvotes: 3