I am experiencing a very strange phenomenon (test device: HTC Desire HD, Android 2.3.5). I know that System.gc()
is needless and discouraged, and I don't try to suggest otherwise, but the point is that it shouldn't cause issues either (i.e. it should be useless at most).
I have an application which contains a GLSurfaceView
in its view hierarchy. The GLSurfaceView
is instantiated and added in the Activity.onCreate()
. Normally, the application works like this:
- User starts the app and goes to mainmenu
- User chooses a mainmenu item which sets the
GLSurfaceView
toView.VISIBLE
- User plays with the in-built game on
GLSurfaceView
- User goes to mainmenu and exits the activity (=>
Activity.finish()
is called)
My Activity.onPause()
looks like this:
mGameThread.pause(); // gameThread is my custom thread class for the in-built game
mGLView.onPause(); // pause the renderer thread
So far so good, everything works fine. However, issues appear after I add the following code to onPause()
(for the case when the user exits the game from the mainmenu):
mGameThread.pause(); // gameThread is my custom thread class for the in-built game
mGLView.onPause(); // pause the renderer thread
if (isFinishing()) {
System.gc();
}
In details: if the Activity
is started for the first time (= i.e. the app process didn't exist before), everything works fine. However, starting from the 2nd start of the activity (= after the first exit from the mainmenu, i.e. after the first Activity.finish()
), the framerate of GLSurfaceView is reduced by 40-50%, the in-built game becomes slow.
If I remove the System.gc()
call, the problem disappears. Moreover, if I do the following, it also gets rid of the problem:
mGameThread.pause(); // gameThread is my custom thread class for the in-built game
mGLView.onPause(); // pause the renderer thread
if (isFinishing()) {
// 1. get layout root of View hierarchy
// 2. recursively remove (detach) all Views
// 3. call GC
System.gc();
}
I didn't add concrete code because it's complex, so I used comments. If I just detach the GLSurfaceView
via removeView()
, it is not enough. The entire view hierarchy needs to be cleared.
Note that I couldn't find any memory leaks (no Activity leak via drawables/statics etc.). Moreover, of course, the gameThread properly exits when the app is closed (I just didn't include its source code).
Any ideas, guesses? Apparently, System.gc()
seems to cause some issues for the Activity/layout destroying mechanism of Android. Again, as I said, if I remove System.gc()
, the problem disappears.