I'm making a game using J2ME and sometimes while testing it I'm getting out of memory exception, I know what it means but how can I solve it ? if I'll call System.gc() in my game loop every time will it help somehow ? Any tips on how to prevent this would be appreciated !
2 Answers
I see you've also asked j2me wtk find memory leak
In my experience, memory leaks don't cause OutOfMemoryExceptions
. All they do is to slowly use up all the memory in the device. And when it's all nearly used up, the device is then forced to call System.gc()
itself.
System.gc()
is a blocking call, meaning it'll make your whole game stall for some microseconds, which of course is annoying. And this is why people go hunting for memory leaks - to prevent the automatic call to System.gc()
.
An OutOfMemoryException
may occur if e.g. you have 1mb memory left, while trying to load a 2mb resource. And while a memory leak may dramatically increase chances of running into a situation like that, your problem is not the memory leak itself, but more likely that you're using too big resources.
Are you using mp3 files for music? Or big images for backgrounds or maps?
You could try calling System.gc()
just before loading big resources, and it might reduce the problem. But the problem doesn't have to be related to your game alone. It could also matter what other apps are running on the device at the same time, and how much memory they use.
You could also try replacing mp3 music with MIDI music, if only just to test if it makes a difference. (Find JavaME optimized MIDI music at IndieGameMusic.com).
And if you do use big images, make sure you optimize them with tools like PNGout or Optipng.
-
thanks mr_lou I'll try all of your suggestions and report back when im done checking. also, program I can use to convert mp3 files to midi ? – user3641760 May 21 '14 at 07:17
-
ok made file images 1MB less in size, didn't help will try to make mp3 files to midi files somehow, anymore suggestion meanwhile ? – user3641760 May 21 '14 at 08:08
-
You don't have to spend time converting the mp3 to midi. Just download some midi and try with that one. The MIDI's at IndieGameMusic.com (most of them anyway) are already optimized for JavaME too. (Meaning their filesize is at an absolute minimum, among other things). – mr_lou May 21 '14 at 09:26
-
the problem is that I need specific sounds and the ones at indiegamemusic doesn't fit to my needs, although I don't think it'll solve my problem anyway the sounds file are total of 114KB and the images that I use are total of 1.08MB after using PNGOUT. – user3641760 May 21 '14 at 10:05
-
Also I've notice that I usually get the out of memory exception after the 4th time or while the 4th time playing a level, my game works as follow, you have a menu where you can select levels, you select a level, it loads the level data from a recordstore, you play it either lose or win and then you're back to the level selection menu. noe sometimes I get the out of memory exception while playing a level for the 4th time, sometimes when loading the level for the 4th time. – user3641760 May 21 '14 at 10:05
-
I even tried each time that I selected a level to make the MyGameCanvas instance null each time you select a level, thought it'll free resources (where all the rendering and calculations take place, the code I've posted in pastebin takes place).. (Made it in 3 posts because I had no characters left to write.. sorry) – user3641760 May 21 '14 at 10:06
-
When testing, it doesn't matter that the music is not what you want. It's just for testing. To see if it makes a difference. That's all. How many kb is your biggest image? – mr_lou May 21 '14 at 14:17
-
biggest is 69.1, I don't know what to do anymore I tried obfsucating, making image size less using the program u recommended me, what else can I try ? – user3641760 May 21 '14 at 15:01
-
I wanted to mention that I find it weird how in the 4th play session of the level I get the out of memory exception because the first 3 play sessions are ok and after each play session the gb should clean all the unused variables which is everything that is used in my game canvas, but it seems that it doesn't clean it because i get the out of memory exception .. no idea how to solve this issue, i would really like someone to help me find out what causing it, I can post a code if someone would like just tell me. I've also tried to reference the canvases instances that are not in use to null .. – user3641760 May 21 '14 at 15:14
-
You refer to code you put in pastebin, but I don't see any pastebin link anywhere in any of your posts... – mr_lou May 21 '14 at 15:42
-
sorry ! here it is : http://pastebin.com/cnpS0asG this is the class where all the computations and rednering of the game itself take place so i imagine the memory leak is in there, if you want to view the entire project, here is z .rar I've uploaded, hopefully you could help me figure out ! http://speedy.sh/cspuT/Zuma.rar – user3641760 May 21 '14 at 15:58
-
hey mr_lou any news ? maybe you found what could be the cause for the OOM exception ? I'm clueless by now and could definitely use someone's help – user3641760 May 22 '14 at 00:05
-
I'd also like to see your class that extends `MIDlet`, to see how you're creating `MyCanvas`. Are you creating a new instance of `MyCanvas` for each level? If yes, that could explain the OOM. – mr_lou May 22 '14 at 04:04
-
here it is : http://pastebin.com/PsKAxtLg I don't create it everytime, when the player chooses a level it does that "Midlet.getDisplay().setCurrent(Midlet.getMyGameCanvas());", so if it's already created it just returning it – user3641760 May 22 '14 at 13:27
-
I've added 3 posts above a rar that contains all the classes incase you want to look at other classes, tried to figure what causing it still no success hopefully you found something – user3641760 May 23 '14 at 08:35
-
Sorry, been busy. Well, one thing I notice is that you use a lot of memory on rendering rotated images for each loop. Not much to do about it though. What you'd usually do is to `null` the objects and call `System.gc()` before creating new objects, but this would make the game slow. I also notice that you're actually creating a `Thread` within a `Thread`. Your `init()` method creates a `Thread` but your `run()` method does also. Try removing one of them, as there's only need for one. Otherwise I'm out of ideas. – mr_lou May 25 '14 at 13:46
-
the reason i did it is because i wanted to make the input thread independent from the ball's calculation thread, because at first i made it 1 thread, but the game is very dynamic it lets you decide what the balls speed will be with an xml file it reads the level properties from, and say the property of speed of the balls is set to 1 for example then I sleep for 20 seconds, 10 + (10 * speed), but if I made it larger number making the speed of the balls slower then the input of the user will be slower and the frog will rotate much more slower, so I decided to seperate them – user3641760 May 25 '14 at 15:41
-
2 posts too long. btw i read emulators use more RAM so is there a chance it'll run on actual devices ? also how can i make the heap size of the emulator larger ? I use oracle sdk 3.4 JavaMEPhone1 device – user3641760 May 25 '14 at 15:42
-
also the oom exceptions happens after playing a level for the 3/4th time and not on the 1/2th time so i think it means that some objects and data types that arn't being used from previous games arn't being cleaned by the gc as far as I understand and I don't see why, correct me if I'm wrong, but from what i've checked it only happens only after playing for the 3/4th time so it means some data types that arn't being used arn't being deleted for some reason from the RAM – user3641760 May 25 '14 at 15:55
-
I just found this doc of the oracle sdk 3.4 emulator http://docs.oracle.com/javame/dev-tools/jme-sdk-3.4/nb/html/toc.htm http://docs.oracle.com/javame/dev-tools/jme-sdk-3.4/nb/html/memmonit.htm#sthref201 it's written that you need to "In the Projects view, right-click the project and select Profile.". I don't see Profile option when right clicking my project in the project view unless im clicking the wrong place ? – user3641760 May 25 '14 at 16:10
-
I thought the OOM Exception you were experiencing was on a real device. Emulators can be set up to have a specific amount of memory. So yes, it's quite probably that your MIDlet will run on a real device. ALWAYS test on a real device. NEVER trust emulators. – mr_lou May 25 '14 at 16:51
-
Unfortunately I can't test it on real device since I can't get my hands on one. On the other hand, my intentions were never to release this application, it's just for school purposes anyway. So about increasing the heap size, how can I do it if I use oracle sdk 3.4 as my emulator ? I've searched the web but found nothing, any chance you could help me with that ? – user3641760 May 25 '14 at 20:09
-
I have no experience with SDK 3.x since Oracle hasn't released a Linux version. But for previous versions, I've used NetBeans as my IDE, and I can edit Emulator properties by going first to the Project Properties, and then go to Manage Emulators. – mr_lou May 26 '14 at 04:59
-
I don't see an option to change the heap size but I see a memory monitor and network monitor button under a tab called tools & Extensions but it's grayed out for the oracle sdk 3.4 emulator. (for the WTK emulator it's not grayed out) – user3641760 May 26 '14 at 10:50
If original file is not too big then no need of decreasing size,you can use jpeg instead...also you can just have specific limit to your local buffer size.and before system.gc() you can make use of Thread.sleep() for testing purpose to check the effect and to give time to Gc.also check with WTK's performance monitor to check actual pick location.

- 1,651
- 12
- 30
-
i've already tried using wtk see what happend : http://stackoverflow.com/questions/23771960/j2me-wtk-find-memory-leak also I compressed the image files to 1MB less, it didn't help, ill try converting mp3 files to mid file and see how it goes, any more ideas beside ? – user3641760 May 21 '14 at 08:03
-
i have posted link there,we can continue over there. Additionally here,you can also clear/nullify/destroy your objects/data structures you used and not needed at current moment. – vITs May 21 '14 at 08:41