System.gc()导致Activity的第二次启动减慢

我遇到了一个非常奇怪的现象(测试设备:HTC Desire HD,Android 2.3.5)。 我知道System.gc()是不必要的,不鼓励的,我不会尝试另外建议,但重点是它不应该引起问题 (即它最多应该没用)。

我有一个应用程序,在其视图层次结构中包含GLSurfaceViewGLSurfaceView被实例化并添加到Activity.onCreate() 。 通常,应用程序的工作方式如下:

  1. 用户启动应用程序并转到mainmenu
  2. 用户选择一个GLSurfaceView单项,将GLSurfaceView设置为View.VISIBLE
  3. 用户在GLSurfaceViewGLSurfaceView内置游戏
  4. 用户进入mainmenu并退出活动(=> Activity.finish()被调用)

我的Activity.onPause()看起来像这样:

 mGameThread.pause(); // gameThread is my custom thread class for the in-built game mGLView.onPause(); // pause the renderer thread 

到目前为止一切顺利,一切正常。 但是,在将以下代码添加到onPause()之后会出现问题(对于用户从主菜单退出游戏的情况):

 mGameThread.pause(); // gameThread is my custom thread class for the in-built game mGLView.onPause(); // pause the renderer thread if (isFinishing()) { System.gc(); } 

详细信息:如果Activity第一次启动(=即之前的应用程序进程不存在),一切正常。 但是, 从活动的第2次开始 (=从主菜单第一次退出后,即在第一次Activity.finish() ), GLSurfaceView的帧率降低了40-50% ,内置游戏变慢。

如果我删除System.gc()调用,问题就会消失。 而且,如果我执行以下操作,它也可以解决问题:

 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(); } 

我没有添加具体代码,因为它很复杂,所以我使用了注释。 如果我只是通过removeView()分离GLSurfaceView ,这还不够。 需要清除整个视图层次结构。

请注意,我找不到任何内存泄漏(通过drawables / statics等没有Activity泄漏)。 此外,当然,当应用程序关闭时,gameThread会正常退出(我只是没有包含其源代码)。

任何想法,猜测? 显然, System.gc()似乎会导致Android的Activity / layout销毁机制出现一些问题。 再说一遍,正如我所说,如果我删除System.gc() ,问题就会消失。

我有Android游戏编程的经验。 我曾经清除层次结构中的所有视图,因为在运行线程时如果调用System.gc(),有时会发生您的线程对某些视图的引用,即使您调用system.gc(),此视图也不会被删除,如果你一直在玩这个游戏,你会注意到你的堆内存开始增长。

这取决于内存泄漏,如果你泄漏一些KB内存,将需要更多的时间来崩溃你的游戏。 它是使用Eclipse Memory Anlyser(Eclipse MAT)并比较堆栈的最佳方式。

Step1:第一次开始游戏时拍摄记忆快照Step2:第二次开始游戏时拍摄记忆快照Step3:现在比较两堆快照,它会告诉你差异。

这是一个非常有用的工具。 我的游戏Apache Attack中存在巨大的内存问题。 我使用这个很棒的工具修复它们。 关注这个ECLIPSE MAT TUTORIAL