Tips for Out Of Memory errors

We’ve seen a few cases where running an app on Android produces Out Of Memory crashes when the game is run multiple times. There is definitely an issue there that hasn’t been completely solved, but here is a tip to see if it helps.

On most phones, the natural orientation of the device is Portrait. By default, the orientation of the game is set in MainActivity using
[java]screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;[/java] This is used in the onCreate of AndroidHarness to change the orientation of the Activity to Landscape using [java]setRequestedOrientation(screenOrientation);[/java]

It appears that when the setRequestedOrientation method is called with a different orientation than the device is already in, the original Activity is destroy and a new Activity is created with the orientation in Landscape. This has nothing to do with jME, it’s just how Android works. The side effect is that a GLSurfaceView and a rendering thread (GLThread) is created during the original create but the rendering thread is not being closing down when the Activity is destroyed and recreated. This results in 2 rendering threads. When the game exits, the new GLThread is closed, but the original GLThread is still active. When the game is started a second time, the same process occurs that again creates 2 rendering threads and only closes 1 of them. Eventually, you get an Out Of Memory crash. jME is properly switched to the new rendering thread when the Activity is recreated, but the original rendering thread is still hanging around.
[java][/java]
This issue of not closing down the original rendering thread also happens when running the Android example (sample app supplied with the Android SDK) without jME. However, there must be some references that are not cleaned up internally in jME that eventually cause the Out Of Memory crash. I have not been able to track down what references are left over, but I have found a way to get around the issue (at least it works for me).
[java][/java]
If you also set the orientation of the game in the Manifest file, then the game will start the first time in the correct orientation and Android will only create 1 rendering thread and close it properly when the game exits.
[java][/java]
To do this, make the following change in the AndroidManifest.xml file:
Original:
[java]
activity android:label="@string/app_name" android:name=“MainActivity”
[/java]
New:
[java]
activity android:label="@string/app_name" android:name=“MainActivity” android:screenOrientation=“landscape”
[/java]

2 Likes

So to create 1 gl thread set landscape mode in the manifest. What about the main activity?
Within the MainActivity should we use screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; or SCREEN_ORIENTATION_PORTRAIT?

Thanks

In MainActivity, set screenOrientation to the same orientation as being set in the AndroidManifest.xml. The key is to make the setting in MainActivity and AndroidManifest.xml match.