Out of memory error when restarting app (Android)

2019-05-05 00:23发布

问题:

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.

回答1:

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.



回答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