11

我遇到了一个很奇怪的现象(测试设备:HTC Desire HD,Android 2.3.5)。我知道这System.gc()是不必要的和气馁的,我不会试图提出其他建议,但关键是它也不应该引起问题(即它最多应该是无用的)。

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

  1. 用户启动应用程序并转到主菜单
  2. 用户选择一个设置为的主菜GLSurfaceView单项View.VISIBLE
  3. 用户玩内置游戏GLSurfaceView
  4. 用户进入主菜单并退出活动(=>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(=第一次退出主菜单后,即第一次后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();
}

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

请注意,我找不到任何内存泄漏(通过可绘制/静态等没有活动泄漏)。此外,当然,当应用程序关闭时,gameThread 会正确退出(我只是没有包含它的源代码)。

任何想法,猜测?显然,System.gc()这似乎对 Android 的 Activity/layout 破坏机制造成了一些问题。同样,正如我所说,如果我删除System.gc(),问题就会消失。

4

1 回答 1

7

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

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

Step1: 第一次开始游戏时 拍摄记忆快照Step2: 第二次开始游戏时拍摄记忆快照 Step3: 现在比较你的两个快照堆栈,它会告诉你不同之处。

这是一个非常有用的工具。我在游戏Apache Attack中遇到了巨大的内存问题。我使用这个很棒的工具修复了它们。按照这个ECLIPSE MAT 教程

于 2012-09-18T07:14:19.250 回答