views:

142

answers:

2

So I installed my app on my ipad and it crashes due to a memory issue. I figured this was because I'm using really big image files so I went back and reduced them all and essentially cut out about 75% of their size by resizing them and then using PNGCrush.

Now, as for running the program, if I have a background image for each of my 4 individual tabs, would it save memory if I were to set the images to Null every time I switch tabs or should I leave them set? I have one page which has a couple dozen images on it as they act as buttons and from what I'm hearing it sounds like I should clear them all when I'm not viewing that page. Is that correct?

Right now when I boot up, I load all of the images for everything in the app in a sort of: "load it now and be done with it" mentality, though from what I've been reading that causes memory issues as there isn't much memory to use. Does this mean every time I switch tabs or views I want to clear all the images from the ones that aren't visible and then reload them when we go back to them? Would this cause an increase in performance? Or at least prevent crashes? My program works in the simulator but when I run it on my ipad it just explodes =/

Thanks!

EDIT: I'm using Monotouch BTW hence everything is in C#

UIImage BG = UIImage.FromFile("Images/Makes/explosion.png");
UIImage basic = UIImage.FromFile("Images/Models/camaro.png");
UIImage advance = UIImage.FromFile("Images/search.png");

AdvancedSearchButton.SetBackgroundImage(advance, UIControlState.Normal);
ImageSearchButton.SetBackgroundImage(basic, UIControlState.Normal);
MainBG.Image = BG;

BG.Dispose();
basic.Dispose();
advance.Dispose();

Now I know in regular C# dispose() doesn't actually "free" memory, but I read something that says that it gets converted to a "release" when it compiles over to obj-c so that would essentially be freeing those objects.

Also, I'm wondering if I would need to dispose() of the individual buttons and the image after I'm no longer viewing them. I was just setting the image to NULL but that gave me errors.

MainBG.Dispose();
AdvancedSearchButton.Dispose();
ImageSearchButton.Dispose();

Thanks so much for the help!

EDIT2:

So I just tried the above code and the background images and everything else are still there and appears as if nothing is actually getting cleared. Suggestions?

+2  A: 

The iPhone does not have virtual memory and it does not have garbage collection. So once something is loaded in the memory it stays in the memory until your code explicitly releases it. If you are not using some resources, you should definitely clean them up as soon as possible.

Also, you should listen to low memory warnings from iOS, which is another opportunity for your code to do some internal clean up.

Franci Penov
"So once something is loaded in the memory it stays in the memory until your code explicitly releases it" Does this mean that if I set a background in tab 1 I'll want to "release it" by setting it to Null? Will that work is or there something else I would need to do.I understand the concepts of freeing/releasing memory, I'm just unaware of how to do it in this instance.The majority of my app is just buttons with images in them.
Adam
You need to send a `release` message to the backing `NSImage` object before you set the pointer to NULL.
Franci Penov
So essentially I would Load my NSImage from my file, set my Image to that, and then release the NS image? And when I switch away from that tab to another I would then set that image to null.I would then rinse and repeat if I went back to that tab. Correct?
Adam
Umh, no. You have to release the NSImage when you switch away from the tab, not immediately after you load it. :-) Btw, if you change your code to show how you are loading the images, people will be able to help you better.
Franci Penov
Updated with Code
Adam
monotouch does actually have garbage collection?!
cvista
It says it supports garbage collection but I'd rather be dealing with memory myself and I'm not entirely sure on how it gets translated over to Obj-C...Other than calling GC.Collect() is there a way to free memory in C#?
Adam
A: 

First off, lazy load your resources unless you have a justifiable reason not to. Secondly, I'm not sure how big your images are, but on large images (ones that are by nature intended for things like backgrounds, or otherwise), generally speaking, I will chop them up into chunks, and load them, again you guessed it, lazily as they're needed.

What you should do is handle your memory warnings properly. Deallocate any resources that are not absolutely critical -- i.e., items on other views in other tabs, or hidden content. You can load them again when you have to.

You should also take a look at using Instruments to find out if you leak (I'm hoping you've already done this), examine your program to see if you can persist some cached resources to disk during low memory situations, etc.

jer