Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Mockup & CodeGen, iPhone & iPad
($9.99)

Make your own iPhone apps
and run them live!
(free)

Manu
($0.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 01-04-2010, 06:58 AM   #1 (permalink)
Divine avenger
 
Johanovski's Avatar
 
Join Date: Nov 2009
Location: Vic, Catalunya (Spain)
Posts: 320
Default Seems that releasing images doesn't do nothing...

Hi all!

Still battling against memory management, and after doing hundreds of tests I've found that my images' releasing methods doesn't free memory at all... I've tried loading all images just when the game starts and, after touching the screen, releasing nearly all the images and follow this with Instruments' object allocations, so I can follow how living memory goes...
What I've found is the following:

- The app starts and loads all the necessary images --> around 18 MB of used memory.
- After touching the screen, the app should releasing nearly all allocated images, so free memory is expected to increase a lot, but after touching the screen... --> around 18 MB of used memory (nearly the same). Ouch!

What happened? I'm posting how I allocate and release images:

************************************************** ************
// IMAGE ALLOCATION:
// How Images are allocated in the main function (EAGLView.m):
texTaques = [[Image alloc] initWithImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sangnormal01" ofType:@"png"]]];
// This calls an Image class' method:
----------------------------------------------------------------------------
// Image.m method:
- (id)initWithImage:(UIImage *)image {
self = [super init];
if (self != nil) {
texture = [[Texture2D alloc] initWithImage:image];
scale = 1.0f;
[self initImpl];
}
return self;
}
// And this calls a Texture2D class' method:
----------------------------------------------------------------------------
// Texture2D.m method:
- (id) initWithImage:(UIImage *)uiImage
{
NSUInteger width,
height,
i;
CGContextRef context = nil;
void* data = nil;;
CGColorSpaceRef colorSpace;
void* tempData;
unsigned int* inPixel32;
unsigned short* outPixel16;
BOOL hasAlpha;
CGImageAlphaInfo info;
CGAffineTransform transform;
CGSize imageSize;
Texture2DPixelFormat pixelFormat;
CGImageRef image;
UIImageOrientation orientation;
BOOL sizeToFit = NO;


image = [uiImage CGImage];
orientation = [uiImage imageOrientation];

if(image == NULL) {
[self release];
NSLog(@"Image is Null");
return nil;
}


info = CGImageGetAlphaInfo(image);
hasAlpha = ((info == kCGImageAlphaPremultipliedLast) || (info == kCGImageAlphaPremultipliedFirst) || (info == kCGImageAlphaLast) || (info == kCGImageAlphaFirst) ? YES : NO);
if(CGImageGetColorSpace(image)) {

if(hasAlpha)
pixelFormat = kTexture2DPixelFormat_RGBA8888;
else
pixelFormat = kTexture2DPixelFormat_RGB565;

//pixelFormat = kTexture2DPixelFormat_RGBA8888;
} else //NOTE: No colorspace means a mask image
pixelFormat = kTexture2DPixelFormat_A8;


imageSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));
transform = CGAffineTransformIdentity;

width = imageSize.width;

if((width != 1) && (width & (width - 1))) {
i = 1;
while((sizeToFit ? 2 * i : i) < width)
i *= 2;
width = i;
}
height = imageSize.height;
if((height != 1) && (height & (height - 1))) {
i = 1;
while((sizeToFit ? 2 * i : i) < height)
i *= 2;
height = i;
}
while((width > kMaxTextureSize) || (height > kMaxTextureSize)) {
width /= 2;
height /= 2;
transform = CGAffineTransformScale(transform, 0.5, 0.5);
imageSize.width *= 0.5;
imageSize.height *= 0.5;
}

switch(pixelFormat) {
case kTexture2DPixelFormat_RGBA8888:
colorSpace = CGColorSpaceCreateDeviceRGB();
data = malloc(height * width * 4);
context = CGBitmapContextCreate(data, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
break;
case kTexture2DPixelFormat_RGB565:
colorSpace = CGColorSpaceCreateDeviceRGB();
data = malloc(height * width * 4);
context = CGBitmapContextCreate(data, width, height, 8, 4 * width, colorSpace, kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
break;

case kTexture2DPixelFormat_A8:
data = malloc(height * width);
context = CGBitmapContextCreate(data, width, height, 8, width, NULL, kCGImageAlphaOnly);
break;
default:
[NSException raise:NSInternalInconsistencyException format:@"Invalid pixel format"];
}


CGContextClearRect(context, CGRectMake(0, 0, width, height));
CGContextTranslateCTM(context, 0, height - imageSize.height);

if(!CGAffineTransformIsIdentity(transform))
CGContextConcatCTM(context, transform);
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB"
if(pixelFormat == kTexture2DPixelFormat_RGB565) {
tempData = malloc(height * width * 2);
inPixel32 = (unsigned int*)data;
outPixel16 = (unsigned short*)tempData;
for(i = 0; i < width * height; ++i, ++inPixel32)
*outPixel16++ = ((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | ((((*inPixel32 >> 8) & 0xFF) >> 2) << 5) | ((((*inPixel32 >> 16) & 0xFF) >> 3) << 0);
free(data);
data = tempData;

}
self = [self initWithData:data pixelFormat:pixelFormat pixelsWide:width pixelsHigh:height contentSize:imageSize];

CGContextRelease(context);
free(data);

return self;
}
- (id) initWithData:(const void*)data pixelFormat:(Texture2DPixelFormat)pixelFormat pixelsWide:(NSUInteger)width pixelsHigh:(NSUInteger)height contentSize:(CGSize)size
{
GLint saveName;
if((self = [super init])) {
glGenTextures(1, &_name);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &saveName);
glBindTexture(GL_TEXTURE_2D, _name);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
switch(pixelFormat) {

case kTexture2DPixelFormat_RGBA8888:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
break;
case kTexture2DPixelFormat_RGB565:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
break;
case kTexture2DPixelFormat_A8:
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
break;
default:
[NSException raise:NSInternalInconsistencyException format:@""];

}
glBindTexture(GL_TEXTURE_2D, saveName);

_size = size;
_width = width;
_height = height;
_format = pixelFormat;
_maxS = size.width / (float)width;
_maxT = size.height / (float)height;
}
return self;
}
************************************************** ************
// ONCE THIS IS DONE, TIME TO FOLLOW THE RELEASING METHODS:
// How images are released in the main method:
[texTaques release];
// This should call the Image.m release method:
----------------------------------------------------------------------------
// Image.m method:
- (void) dealloc
{
//NSLog(@"RELEASE Image");

// texture is a Texture2D object, so this will call the Texture2D dealloc method
[texture release];

[super dealloc];
}
----------------------------------------------------------------------------
// Texture2D.m (which inherits from NSObject) method:
- (void) dealloc
{
//NSLog(@"RELEASE Texture2D");

[super dealloc];
}
************************************************** ************

I've expected this should work, but when release is called no memory is freed at all, so seems that something is going really wrong...

Any idea about this? Any help will be appreciated, really!

Thanks in advance.
Johanovski is offline   Reply With Quote
Old 01-04-2010, 09:56 AM   #2 (permalink)
Registered Member
 
Join Date: Nov 2009
Location: Helsinki
Posts: 215
Default

I don't have experience of Open GL ES, but it seems that you never free/release the texture from memory. Your dealloc in Texture2D calls NSObject dealloc, but it won't free the memory for the texture. Looking at the cocos2d source for Texture2D, they have in the dealloc:

Code:
	if(_name)
		glDeleteTextures(1, &_name);
fiftysixty is offline   Reply With Quote
Reply

Bookmarks

Tags
allocations, image, memory, release, texture2d

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



» Advertisements
» Online Users: 251
21 members and 230 guests
ADY, bookesp, ckgni, dacapo, Dani77, DarkAn, Davey555, Desert Diva, HemiMG, iDifferent, jakerocheleau, JasonR, LEARN2MAKE, nobre84, prchn4christ, Rudy, ryantcb, Speed, themathminister, theone8one
Most users ever online was 1,187, 10-11-2011 at 08:09 AM.
» Stats
Members: 158,885
Threads: 89,230
Posts: 380,766
Top Poster: BrianSlick (7,129)
Welcome to our newest member, bookesp
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 02:39 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0