活动堆栈已满:OutOfMemoryError

时间:2018-02-09 14:52:21

标签: android out-of-memory

我的应用程序设计有侧面菜单,因此基本上您可以从任何活动启动任何活动。如果我使用Android后端堆栈的默认行为启动活动,则活动会相互堆叠,直到手机内存已满并导致非常可怕

  

02-09 15:43:12.807 1860-1868 /? E / System:java.lang.OutOfMemoryError:尝试抛出OutOfMemoryError时抛出OutOfMemoryError;没有可用的堆栈跟踪

现在我的问题是:

  1. 我是否应该使用其他启动模式(REORDER_TO_FRONT,CLEAR_TOP)启动活动,但所有这些都会使后退按钮的行为变得更糟?
  2. 如果内存变满,GC会不会实际收集一些活动,而我的问题可能是我只是有一些强引用指向它们,使它们无法从内存中清除?
  3. 请有人解释一下,谢谢!

1 个答案:

答案 0 :(得分:1)

当活动放在后台堆栈上时,Android通常会将实例保留在内存中。当内存不足时,后台堆栈活动将被关闭(这包括调用onSaveInstanceState() onDestroy()),但系统会保留重新创建它们所需的信息,以防用户导航回来。
保留的信息很小,不应该是一个问题,除非您有数百个活动堆叠。另一方面,一旦被销毁,活动实例将永远不会被重用并且必须是垃圾收集的,否则它构成了Context泄漏,which mays not be obvious to spot

一些建议:

  1. 启用StrictMode,特别是detectActivityLeaks()来检测活动(以及其他Android对象)泄漏

    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
            .detectActivityLeaks()
    
            // or even
            .detectAll()
    
            .penaltyLog()
            // or
            .penaltyDeath()
    
            .build());        
    
  2. 使用Android Studio的内存分析器。 Heap dumps可以显示引用的位置。旧的内存监视器有分析器任务来查找泄漏的活动。据我所知,Android Studio 3.0中没有等效的

  3. 尝试在设备的开发者选项中启用和不启用不要保留活动选项。启用它可以使活动生命周期更具可预测性。

  4. 使用LeakCanary

  5. 等库