 |
 |
|
 |
06-25-2009, 08:09 AM
|
#1 (permalink)
|
|
New Member
Join Date: Jun 2009
Posts: 5
|
Need help with memory management
hey guys!
i have got the following problem: with a timer i call the function draw repeatly (in the timer runLoop function) and found out, that the following commands will increase the memory usage permanently:
Code:
NSNumber *n = [NSNumber numberWithFloat:self.number];
shouldn't this be autoreleased?
Code:
NSString *num = [formatter stringFromNumber:n]];
here formatter is a NSNumberFormatter, initialized in init
Code:
self.drawView.frame = CGRectMake(self.x, self.y, self.width, self.height);
a CGRect is only a structure, right? why is this allocating memory constantly?
i also tried to add a NSAutoReleasePool to the timer function, but that is also not working. furthermore, i tried to alloc the NSString and release it again at the end of the function, but that didn't help.
thanks in advice
xash
|
|
|
06-25-2009, 09:34 AM
|
#2 (permalink)
|
|
Magic Hands' Daddy
Join Date: Aug 2008
Location: Memphis, TN, USA
Age: 22
Posts: 1,372
|
what makes you so certain that these pieces of code are the cause of your ever-increasing memory usage?
|
|
|
06-25-2009, 09:47 AM
|
#3 (permalink)
|
|
New Member
Join Date: Jun 2009
Posts: 5
|
Quote:
Originally Posted by smithdale87
what makes you so certain that these pieces of code are the cause of your ever-increasing memory usage?
|
i reduced the program to the very basic and then i did many tests by commenting various commands. And when i commented those, the memory usage didn't increase.
|
|
|
06-25-2009, 10:06 AM
|
#4 (permalink)
|
|
Magic Hands' Daddy
Join Date: Aug 2008
Location: Memphis, TN, USA
Age: 22
Posts: 1,372
|
Well nothing looks out of place at first glance.
Can you post some more code in the context that you're using it in?
|
|
|
06-25-2009, 10:47 AM
|
#5 (permalink)
|
|
New Member
Join Date: Jun 2009
Posts: 5
|
well...i try to keep it as brief as possible
the Timer class:
Code:
#import "Timer.h"
@implementation Timer
- (id)setTime:(float)theTime delegate:(id)theDelegate selector:(SEL)theSelector repeats:(BOOL)doRepeat
{
time = theTime;
delegate = theDelegate;
selector = theSelector;
repeats = doRepeat;
timer = [NSTimer scheduledTimerWithTimeInterval:theTime target:self selector:@selector(runLoop:) userInfo:nil repeats:doRepeat];
return self;
}
- (void)restart
{
timer = [NSTimer scheduledTimerWithTimeInterval:time target:self selector:@selector(runLoop:) userInfo:nil repeats:repeats];
}
- (void)stop
{
[timer invalidate];
}
- (void)runLoop:(NSTimer *)theTimer
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[delegate performSelector:selector];
[pool release];
}
@end
i've got a base class Base.m
Code:
#import "Base.h"
@implementation Base
- (id)init
{
entities = [[NSMutableArray alloc] initWithCapacity:0];
return self;
}
- (id)initInView:(UIView *)theView
{
parentView = theView;
return [self init];
}
- (void)start
{
[self draw];
for(Base *entity in entities) [entity start];
}
- (void)end
{
[timer stop];
for(Base *entity in entities) [entity end];
}
- (void)draw
{
self.drawView.frame = CGRectMake(self.x, self.y, self.width, self.height);
for(Base *entity in entities) [entity draw];
}
- (void)addEntity:(Base *)theEntity
{
[entities addObject:theEntity];
}
- (void)removeEntity:(Base *)theEntity
{
[entities removeObject:theEntity];
[theEntity release];
}
- (void)dealloc
{
for(Base *entity in entities) [self removeEntity:entity];
[entities release];
[super dealloc];
}
@end
and a game class:
Code:
#import "Game.h"
@implementation Game
- (id)init
{
[super init];
hud = [[Hud alloc] initInView:parentView];
[self addEntity:hud];
return self;
}
- (void)start
{
[super start];
timer = [[Timer alloc] setTime:0.01 delegate:self selector:@selector(draw) repeats:YES];
}
- (void)dealloc
{
[timer stop];
[timer release];
[super dealloc];
}
@end
game will alloc the hud class (inherited from base class) and include it into its entities. then, when game is started, it runs the timer, which will call the draw method every 1/100 s.
in the hud class draw method, there are the previously mentioned commands (except for the CGRectMake, which is in the super draw method).
Code:
- (void)draw
{
NSNumber *n = [NSNumber numberWithFloat:self.number];
NSString *num = [NSString alloc];
num = [formatter stringFromNumber:n];
// the rest is unimportant
[super draw];
[num release];
}
i hope that this is comprehensible
|
|
|
06-25-2009, 11:14 AM
|
#6 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,570
|
Here's one problem:
Code:
NSString *num = [NSString alloc];
num = [formatter stringFromNumber:n];
You alloc some memory for a string, and you never use that memory or release it. It's probably getting leaked.
Your code basically says "reserve some memory for a string, and point the pointer 'num' at it." And then "point the pointer 'num' at a different string instead.' You don't need to alloc any memory if you're just going to point the pointer at a different object. This code would be just fine:
Code:
NSString *num;
num = [formatter stringFromNumber:n];
Also, it's more typical to release objects right after you add them to an array - that way when array gets deallocated, all the objects inside get deallocated too (because they only had a retaincount of one.)
I can see from your code that the objects in your array get a retaincount of two - one from when they were created, and one from adding to the array. That's why you find yourself having to release them after you remove them.
If you've added them to the array and then released them, then a simple [entities removeObject:theEntity] would cause the entity's retaincount to go to zero, and it would be destroyed. Futhermore, assuming the array had a retaincount of one, [entities release] would send a release to every object in the array, causing their counts to go to zero, causing them to be destroyed.
If what I'm saying seems confusing, then you should read up on memory management:
http://www.stepwise.com/Articles/Tec...-03-11.01.html
__________________
Last edited by smasher; 06-25-2009 at 11:17 AM.
|
|
|
06-25-2009, 11:49 AM
|
#7 (permalink)
|
|
New Member
Join Date: Jun 2009
Posts: 5
|
thanks for your replay, the link and your explanation! i already thought that it has to be that way, but i couldnt figure out, how to get a fast access to the entity in the array. is there any possibility to create a key or something for an array item? well...i could add something like an entiyName property to each object and go through all entities to find it, but is there any easier method for that?
well...i already tried to not allocate the NSString (exactly the way you suggested), but that did not work either. also the NSNumber should be autoreleased, as far as i understood that. and what about the CGRectMake?
what could that be?
or am i missinterpreting the instruments? everything is increasing except of net bytes. is this the important number or all other things (#net, overall bytes, #overall)?
|
|
|
06-25-2009, 04:18 PM
|
#8 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,570
|
Quote:
Originally Posted by xash
thanks for your replay, the link and your explanation! i already thought that it has to be that way, but i couldnt figure out, how to get a fast access to the entity in the array. is there any possibility to create a key or something for an array item? well...i could add something like an entiyName property to each object and go through all entities to find it, but is there any easier method for that?
|
I don't understand the connection between my explaination and "fast access to the entity in the array" , so we might be misunderstanding each other - however you can get objects directly from the array using objectAtIndex: . If you want to store objects by name, you could use a dictionary instead, with the name as the key. Dictionaries do not keep items in order, though.
Quote:
|
or am i missinterpreting the instruments? everything is increasing except of net bytes. is this the important number or all other things (#net, overall bytes, #overall)?
|
You may be fine! Overall Bytes and Overall # are the total number (and size) of objects that were allocated EVER, even if you released them properly. Those will always go up.
The Net # and Net bytes are the amount you're using now - they're also represented in the blue graph at the top of instruments. They will go up and down a little. If they climb like a mountainside and wind up over 8-12MB, you're in trouble.
__________________
|
|
|
06-25-2009, 04:33 PM
|
#9 (permalink)
|
|
New Member
Join Date: Jun 2009
Posts: 5
|
i ment that I add e.g. the hud object to the object game, and add it then to the entities array to automatically call the function draw of hud.
but in the games draw method i also have to access the hud object to change some properties. when i release it, i can't simply write hud.speed e.g.
well, i will try the NSDictionary approach, thanks for the advice!
ok, the net bytes number isn't increasing and the diagram is always blue and not getting bigger. do i need to take care of the # net? because this is also increasing permanently.
|
|
|
 |
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
» Advertisements |
» Online Users: 281 |
| 22 members and 259 guests |
| aderrington, Alexman, AlexTheMighty, arcturus, Bertrand21, Cathy, Chilibird, Corund, evana, Falcon80, fanstarmike, Glnn, headkaze, jhaynie, kalygraphix, mac514, pereorra, shuvo1879, Slecorne, smrtital, Stan Edge, tlikyu |
| Most users ever online was 779, 05-11-2009 at 09:55 AM. |
» Stats |
Members: 24,228
Threads: 39,007
Posts: 171,098
Top Poster: smasher (2,570)
|
| Welcome to our newest member, SSL Matrix |
|