Advertise Books Events Forum News Social Networking Support Us

sdkIQ for iPhone
($4.99)

Shape Up
($0.99)

Your First iPhone App
($1.99)

iVidCam Free
(free)

Kid Art
($0.99)

iPUBQUIZ
(£1.19)

ArtStudio
($3.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 06-25-2009, 08:09 AM   #1 (permalink)
New Member
 
Join Date: Jun 2009
Posts: 5
Question 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
xash is offline   Reply With Quote
Old 06-25-2009, 09:34 AM   #2 (permalink)
Magic Hands' Daddy
 
Join Date: Aug 2008
Location: Memphis, TN, USA
Age: 22
Posts: 1,372
Send a message via ICQ to smithdale87 Send a message via AIM to smithdale87 Send a message via Skype™ to smithdale87
Default

what makes you so certain that these pieces of code are the cause of your ever-increasing memory usage?
__________________
Games
AppRoach - (v1.0)
7 Deaths In Nagamachi (v1.1)
Segment (v1.2)
ThumStruck Free (v1.5)
Plummet - new (v1.0)
ThumStruck 2! - Coming Soon

Apps
ArtsMemphis - (v1.0)
Elvis Mobile (v1.1)
DataLoss DB - (v1.1)
Lovers & Haters - (v1.0)
smithdale87 is offline   Reply With Quote
Old 06-25-2009, 09:47 AM   #3 (permalink)
New Member
 
Join Date: Jun 2009
Posts: 5
Default

Quote:
Originally Posted by smithdale87 View Post
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.
xash is offline   Reply With Quote
Old 06-25-2009, 10:06 AM   #4 (permalink)
Magic Hands' Daddy
 
Join Date: Aug 2008
Location: Memphis, TN, USA
Age: 22
Posts: 1,372
Send a message via ICQ to smithdale87 Send a message via AIM to smithdale87 Send a message via Skype™ to smithdale87
Default

Well nothing looks out of place at first glance.

Can you post some more code in the context that you're using it in?
__________________
Games
AppRoach - (v1.0)
7 Deaths In Nagamachi (v1.1)
Segment (v1.2)
ThumStruck Free (v1.5)
Plummet - new (v1.0)
ThumStruck 2! - Coming Soon

Apps
ArtsMemphis - (v1.0)
Elvis Mobile (v1.1)
DataLoss DB - (v1.1)
Lovers & Haters - (v1.0)
smithdale87 is offline   Reply With Quote
Old 06-25-2009, 10:47 AM   #5 (permalink)
New Member
 
Join Date: Jun 2009
Posts: 5
Default

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
xash is offline   Reply With Quote
Old 06-25-2009, 11:14 AM   #6 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
smasher's Avatar
 
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,570
Default

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.
smasher is offline   Reply With Quote
Old 06-25-2009, 11:49 AM   #7 (permalink)
New Member
 
Join Date: Jun 2009
Posts: 5
Default

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)?
xash is offline   Reply With Quote
Old 06-25-2009, 04:18 PM   #8 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
smasher's Avatar
 
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,570
Default

Quote:
Originally Posted by xash View Post
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.
__________________
smasher is offline   Reply With Quote
Old 06-25-2009, 04:33 PM   #9 (permalink)
New Member
 
Join Date: Jun 2009
Posts: 5
Default

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.
xash is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Enter the iPhone App Challenge!  Win $500!
» 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
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 03:45 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0