android - System.gc() 导致从 Activity 的第二次启动开始变慢

标签 android android-layout garbage-collection android-view

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

我有一个应用程序,在其 View 层次结构中包含一个 GLSurfaceViewGLSurfaceView 被实例化并添加到 Activity.onCreate() 中。通常,应用程序是这样工作的:

  1. 用户启动应用程序并转到主菜单
  2. 用户选择一个主菜单项,将 GLSurfaceView 设置为 View.VISIBLE
  3. 用户在 GLSurfaceView 上玩内置游戏
  4. 用户转到主菜单并退出 Activity (=> 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 第一次 启动(= 即应用进程之前不存在),一切正常。但是,从 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();
}

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

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

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

最佳答案

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

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

第一步: 第一次开始游戏时拍摄内存快照 第二步: 第二次开始游戏时拍摄内存快照 第三步: 现在比较你的两个快照堆栈,它会告诉你不同之处。

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

关于android - System.gc() 导致从 Activity 的第二次启动开始变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11601914/

相关文章:

ruby - Rails 算法后内存泄漏?

java - Android - Activity 构造函数与 onCreate

android - 通过AlarmManager 设置不准确的警报时会有多少延迟?

android - encode() 私钥在 "AndroidKeyStore"返回 null

java - 在 getInstance() 方法或实例变量定义中初始化单例之间是否存在功能差异

android - 如何在谷歌地图中心创建雷达动画?

android - 主题更改不适用于 <4.0,因为它应该

android - 将 coordinatorLayout anchor 与 constraintLayout 一起使用

Scala 大列表分配导致大量垃圾收集

Java获取一周中最近传入的某一天的日期