Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android System.gc()导致从活动的第二次启动开始减速_Android_Android Layout_Garbage Collection_Android View - Fatal编程技术网

Android System.gc()导致从活动的第二次启动开始减速

Android System.gc()导致从活动的第二次启动开始减速,android,android-layout,garbage-collection,android-view,Android,Android Layout,Garbage Collection,Android View,我遇到了一个非常奇怪的现象(测试设备:HTC Desire HD,Android 2.3.5)。我知道System.gc()是不必要和不受鼓励的,我不想提出其他建议,但重点是它也不应该引起问题(也就是说,它最多应该是无用的) 我有一个应用程序,它的视图层次结构中包含一个GLSurfaceView。GLSurfaceView被实例化并添加到活动.onCreate()中。通常,应用程序的工作方式如下: mGameThread.pause(); // gameThread is my custom t

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

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

mGameThread.pause(); // gameThread is my custom thread class for the in-built game
mGLView.onPause(); // pause the renderer thread
  • 用户启动应用程序并进入主菜单
  • 用户选择一个主菜单项,将
    GLSurfaceView
    设置为
    视图。可见
  • 用户在
    GLSurfaceView上玩内置游戏
  • 用户转到主菜单并退出活动(=>
    activity.finish()
    被调用)
  • 我的
    Activity.onPause()
    如下所示:

    mGameThread.pause(); // gameThread is my custom thread class for the in-built game
    mGLView.onPause(); // pause the renderer thread
    
    到目前为止一切正常。但是,在我将以下代码添加到
    onPause()
    (针对用户从主菜单退出游戏的情况)后,会出现问题:

    详细说明:如果
    活动是第一次启动的(=即应用程序进程以前不存在),则一切正常。但是,从活动的第二次开始(=第一次从主菜单退出后,即在第一次
    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等没有活动泄漏)。此外,当然,当应用程序关闭时,游戏线程会正确退出(我只是没有包括它的源代码)


    有什么想法吗,猜猜看?显然,
    System.gc()
    似乎给Android的活动/布局破坏机制带来了一些问题。同样,正如我所说,如果我删除
    System.gc()
    ,问题就会消失。

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

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

    步骤1: 当你第一次开始游戏时,拍摄记忆快照 第二步: 在第二次开始游戏时拍摄记忆快照 第三步: 现在比较两个快照堆栈,它将告诉您区别

    这是一个非常有用的工具。我在游戏中遇到了巨大的内存问题。我用这个很棒的工具修复了它们。
    遵循此

    只是为了让它更复杂:如果我在Debug.startMethodTracing()和Debug.stopMethodTracing()之间围绕onPause()的主体“,问题消失了!也就是说,当我试图分析以发现问题时,问题消失了。您是否尝试过删除-if isFinished语句并将其移动到onDestroy?也许这很有帮助@Martijn Van Mierloo:是的,但没有帮助。我尝试了所有这些定位方法。我在某个地方读到,onDestroy()和onPause()不是清理的理想场所,因为onDestroy()保证在每次完成活动时都会被调用,它可能在下次开始活动时被调用,因此,如果will调用的是onDestroy,那么onCreate。我在Apache攻击中遇到了我。好的,清理工作的最佳位置是onStop(),所以试着把它放在那里……关于android内存管理的讨论真的很好:如果你正在清空资源,那么你应该调用System.gc()。如果调用System.gc(),可能会出现某些资源处于释放其资源之间的情况,但正如您调用System.gc()时,它的finalize()方法已被调用,因此它不会被gc收集,因为finalize()是在gc收集对象时被调用的,如果它已经被调用,它将不会被垃圾收集。我不是一个以英语为母语的人,我试着用我能用的最好的方式让你们理解。谢谢,这一点更清楚,但他们(通常)会否定什么呢?GL纹理以本机方式存储,可以通过相应的GL调用删除。那么它们是什么呢?tex-coord缓冲区和类似的东西都是纯(int)Java数组。根布局设置为空;2.GC被调用,FielalIZE()被调用,但是我们处于释放资源的中间,所以布局没有被收集;3.当GC再次尝试释放它时,finalize()将不会被调用(因为它只能调用一次),因此只有托管端会被释放,并且不会释放本机端(=本机Android surface)结果:bug出现在Desire HD(Android 2.3.5)上,而不会出现在三星Galaxy S3(Android 4.0.3)上。关于launchMode:我知道它是如何工作的。但我认为它不应该参与其中,也就是说,如果改变启动模式可以解决问题,那么它(最多)就是一个解决办法,但问题的根源在于其他地方。(可能与您所写的终结器问题有关。)