Memory usage difference windows vs iphone

Previous topic - Next topic

kwagner

Hi,
I've had some complaints about my App crashing on startup and not running on older devices. I found out this was an issue of not having enough memory, which surprised me because it only uses 20MB of ram running on windows. I ran the Xcode activity monitor and see my App using 123MB of ram! Same graphics and music, same code. Why the huge difference? I have about 7MB of PNG's loaded as sprites, 1.1MB of wav files as sounds, and 1MB of mp3 loaded as music. Any help in getting my App down to size would be appreciated :)

doimus

QuoteI have about 7MB of PNG's loaded as sprites...

It's this - 99% sure.

PNGs are compressed images - when you use them in your app they use as much memory as when uncompressed. Try converting them to bmp to see how much memory they actually take.

Under windows, your images are "sent" to video memory and that's the reason why only 20MB are taken. Windows Task manager doesn't show video memory usage, it only shows how much RAM your app uses.
All your images/textures are stored on graphics card memory, actually.

On iPhone, all RAM is shared between everything (graphics, app, OS, whatever - it all has to fit into 128MB)

kwagner

I figured it was, but didn't understand the discrepancy. The video ram makes sense. Some of the PNGs I have are fullscreen. If I reduce them by 50%, then display them with zoomsprite at 2x, would memory be reduced any, or would it get used in the zoom function?

MrTAToad

Scaling a sprite should save memory as it should only be dealing with the original sprite and placing onto the already defined back buffer.  Of course, that comes at the expense of scaling an object, which if you have a lot, could slow things down.

Crivens

When do you load them? Originally (when only using a PC) I loaded the lot when the program first runs, but now (for iOS) I tend to only load everything for a particular section (eg. main menu) then unload it all after I leave the section. Some sections that I have that are graphic intensive I tend to only load the sprites when they are needed the first time (ie. first time they are seen as somethings might not be seen at all by the user if they don't select an option. eg. a different graphic for a button highlight when pressed).

Cheers
Current fave quote: Cause you like musicians and I like people with boobs.

kwagner

I have a few fullscreen animations (20-30 frames) that I'm sure are the main culprits. If I load on-demand, I don't know that it would be fast enough to keep up with the animation speed. I think I can get by with scaling them, as basically the only thing the game is doing at that time is displaying 1-5 images, then waiting 30-50ms for the next frame.

Crivens

20-30 frames of full Retina resolution? That would be quite a bit. Try loading in each frame into the same sprite and showing that each time. Might be fine for a simple animation that updates only every 30ms or so. Then only using the one sprite bank to show it, and can unload that when finished with the animation.

Scaling is a good idea though. Something I did (game selector screen) had all the game pictures for a level on one screen and initially I just scaled (stretchsprite or whatever) the main level pictures down on the fly. No worries. However when changed level it was a bit too slow (felt like was slow to react). Instead I just manually made smaller scaled versions myself and loaded them instead for that screen (keeping the large pictures for the actual game). Was much better. In the future I plan to make a routine to load all sprites at the beginning of the program, detect the iOS resolution (always have media for max), then scale down everything accordingly and save out the sprites in the correct sizes for next time. Plus still load and unload them when I need them (not actually load all sprites for the complete game into sprite banks at the beginning). Should work a treat.

Cheers
Current fave quote: Cause you like musicians and I like people with boobs.

kwagner

Yeah I knew it was a lot when the artist had the idea (even the 480x320 we settled on instead of full resolution) but it seemed to work in testing and I didn't have any issues on my development ipod (4th gen, though). When I started getting ipad and 2nd gen ipod users with issues I looked into it (I didn't know Xcode had profiling tools, shows how much I've used it). There's a few things that should be ok with loading on-demand (the full-screen tutorial images, for example, since they only change when the user taps a button). I will do some testing to see whether on-demand loading is fast enough for realtime animation or not. Thanks all for the advice so far :)

hardyx

If you don't use all the resources at once, consider loading in each level or phase. Try to compress the wavs (16 bit instead 32 bits and mono instead stereo) or use a compressed format like mp3 or ogg. I don't know if this formats works in iPhone.

kwagner

Yeah the problem is all the resources are pretty much used at once. It's a card game, no levels or anything so there's no real clear breaks for loading or unloading. I'll look into the wav size and how many buffers are being used as well (should only need one).

MrTAToad

Yes - the router I've got from my ISP is a bit too security concious :)

kwagner

Thanks guys, using a bit of both techniques I got memory usage from 123MB down to 50MB :)

Crivens

Ok, I didn't know how to track memory in XCode until someone mentioned it above. I'm using the "Run with Performance tool option" and looking at "Allocations" and I can see that my memory keeps building in certain places regardless of what I do to clear things. Is this the right tool to use though?

I thought using loadsprite "",spriteid would clear out the memory for a sprite which is what I am using all over the place and my simple PC task manager checks seemed fine (I see now from this thread that it doesn't check video card memory). So using the performance tool in XCode I used this code:-
Code (glbasic) Select
CLEARSCREEN
ttime=GETTIMERALL()
LOADSPRITE "",padlock
WHILE GETTIMERALL()-ttime<10000
PRINT "1",0,0,kern
SHOWSCREEN
WEND
CLEARSCREEN
ttime=GETTIMERALL()
LOADSPRITE "Media/padlock.png",padlock
WHILE GETTIMERALL()-ttime<10000
PRINT "2",0,0,kern
SHOWSCREEN
WEND
CLEARSCREEN
ttime=GETTIMERALL()
LOADSPRITE "",padlock
WHILE GETTIMERALL()-ttime<10000
PRINT "3",0,0,kern
SHOWSCREEN
WEND
CLEARSCREEN
ttime=GETTIMERALL()
LOADSPRITE "Media/padlock.png",padlock
WHILE GETTIMERALL()-ttime<10000
PRINT "4",0,0,kern
SHOWSCREEN
WEND


Pretty simple really, and I tried it with showing the print lines and then afterwards without (just to make sure the font prints weren't effecting things). Both show the memory keeps being used up more and more. My final test showed a usage of 5.06mb at step 1, which went to 5.34mb at step 2, 5.33mb at step 3 (did it just clear out the pointer and not the actual sprite graphic?), and then 5.61 at step 4. Obviously showing that memory was being taken up even with my use of loadsprite "",padlock.

Am I using the wrong memory clearing command for sprites on the iPhone, or is there a problem with clearing sprites using this method using loadsprite?

Cheers
Current fave quote: Cause you like musicians and I like people with boobs.

Crivens

Just a bit more info. I put this code in:-
Code (glbasic) Select
ttime=GETTIMERALL()
ttotal=0
tsprite=GENSPRITE()
WHILE 1=1
IF GETTIMERALL()-ttime>100 
LOADSPRITE "Media/1-1.png",tsprite
INC ttotal
ttime=GETTIMERALL()
ENDIF
PRINT ttotal,0,0,10
SHOWSCREEN
WEND


And it eventually crashes out. The allocation program shows it steadily using more memory, but frees up a tiny bit each time (seen by peaks on the graph). Note I also added  LOADSPRITE "",tsprite directly after the loadsprite command and it makes no difference.

Cheers

[attachment deleted by admin]
Current fave quote: Cause you like musicians and I like people with boobs.

ampos

I am having similar problems.

Please try loading an unexistent file instead "" (loadsprite "prrt",1)