4

I am working on an game that uses 5 large images that are around 900x600. When I exit the game(press the back button) and then try to launch the game, I get the following error:

12-29 15:59:16.633: E/AndroidRuntime(18642): FATAL EXCEPTION: GLThread 17
12-29 15:59:16.633: E/AndroidRuntime(18642): java.lang.OutOfMemoryError: (Heap  Size=20423KB, Allocated=3473KB, Bitmap Size=77KB)
12-29 15:59:16.633: E/AndroidRuntime(18642):    at org.andengine.opengl.util.GLHelper.getPixelsARGB_8888(GLHelper.java:165)
12-29 15:59:16.633: E/AndroidRuntime(18642):    at org.andengine.opengl.util.GLHelper.getPixels(GLHelper.java:41)
12-29 15:59:16.633: E/AndroidRuntime(18642):    at org.andengine.opengl.util.GLState.glTexImage2D(GLState.java:641)
12-29 15:59:16.633: E/AndroidRuntime(18642):    at org.andengine.opengl.texture.bitmap.BitmapTexture.writeTextureToHardware(BitmapTexture.java:120)
12-29 15:59:16.633: E/AndroidRuntime(18642):    at org.andengine.opengl.texture.Texture.loadToHardware(Texture.java:137)
12-29 15:59:16.633: E/AndroidRuntime(18642):    at org.andengine.opengl.texture.TextureManager.updateTextures(TextureManager.java:254)
12-29 15:59:16.633: E/AndroidRuntime(18642):    at org.andengine.engine.Engine.onDrawFrame(Engine.java:621)
12-29 15:59:16.633: E/AndroidRuntime(18642):    at org.andengine.opengl.view.EngineRenderer.onDrawFrame(EngineRenderer.java:105)
12-29 15:59:16.633: E/AndroidRuntime(18642):    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1363)
12-29 15:59:16.633: E/AndroidRuntime(18642):    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1118)

This is really perplexing since I unload all the textures before the application is destroyed. I know these 5 images are causing the error because when I skipped loading them altogether, I did not get any errors. To make sure all textures were unloaded, I loaded the textures and right after unloaded them. I then exited and relaunched the game but received the same error. The textures do not have any static references either. I also used the MAT to see how much memory I was using in game and noticed that I was only using 2.5MB, so I have no idea why the error is saying "heap size = 20MB." The only way I have managed to solve the error for the time being is to include

system.exit(0);

which I know I shouldn't be using, but I am completely out of ideas.

EDIT: I made sure the textures were being unloaded. I had a button in game that would unload all the textures. When I pressed it all the textures went black which I assume unloaded the textures. The general approach I used when unloading textures was just to say

someTexture.unload();

which is an andEngine method. I'm not sure what happens beyond that.

EDIT 2: I am loading the textures in a method called onCreateResources() and I unload them onDestroy(). Those are the only two places I manipulate the textures.

eBehbahani
  • 1,579
  • 5
  • 19
  • 41
  • 1
    Are you sure the textures are released? How are you _unloading_ them? – K-ballo Dec 29 '12 at 23:29
  • You are using a different Thread to work with the Images, did you explicitly destroy the old Thread before creating a new one? – Sam Dec 29 '12 at 23:32
  • Are you using Bitmap.recycle() ? :) Also, try to force GC by calling it a few times in succession OR increase the heap size by using the cmdline arguments -Xmx – Shark Dec 29 '12 at 23:36
  • 1
    Are you unloading them in your onPause() and reloading them in your onResume() methods? The stacktrace alone isn't helping here... so, show us. – Shark Dec 29 '12 at 23:39
  • I updated the post to show how I remove the textures. I only unload the textures onDestroy(). – eBehbahani Dec 29 '12 at 23:39

2 Answers2

2

If I recall correctly from the Android API: Pressing the back button does not necessarily mean onDestroy(). The Android OS takes care of garbarge collection for you and calls onDestroy() when it feels like it needs to (for example, when you have launched more apps after pressing back button).

However, there are some ROMS that allow you to "kill" the app by long-pressing the back button.

Can you try unloading the textures from onStop() and report back??

EDIT: Did not see Shark's reply. OnPause() also works --same concept... in fact onPause() is always called before OnStop() so it may be a better solution.

preOtep
  • 191
  • 2
  • 11
  • I just did and am still getting the same error. I also checked: onDestroy() does get called when I press back (via logcat). Thanks for the suggestion though. – eBehbahani Dec 29 '12 at 23:53
2

The Garbage Collector doesn't free immediately unused object memory, so if you try to reload new bitmaps after a short, there is no free memory to use for that.

Maybe you should use WeakReference: JVM must free WeakReference objects before throwing an OutOfMemoryException. An example could be found here: http://developer.android.com/training/displaying-bitmaps/display-bitmap.html

gioid
  • 56
  • 1
  • 5
  • That seems likely, but I still see the error even after I wait for a couple minutes after I have closed the app. – eBehbahani Dec 30 '12 at 00:25