我知道如果没有实际代码,这似乎无法确定,但请耐心等待。我认为可以从症状中确定一些东西。
我有一个层次结构浏览器,层次结构的每个级别都由它自己的活动显示。如果检查层次结构的分支太多,则会抛出OutOfMemoryError
异常。这听起来像是内存泄漏,但是随意查看代码并没有发现任何明显的内容,因此在进行更彻底的调查之前,我想对Java和Android的某些方面进行一些澄清。
首先,我可以依赖未使用的活动在抛出OutOfMemoryError
之前进行垃圾回收吗?如果情况并非如此,我会认为这是奇怪的行为,但它会解释我遇到的所有事情。
其次,Dalvik垃圾收集器可以收集循环引用吗?我不认为我有,但如果不能,我会知道在我的代码中寻找它。
我知道有一种方法可以在Android应用程序中泄漏内存,方法是从程序生命周期内的地方创建引用,但同样,我不认为我这样做。例如,我没有以编程方式创建任何UI控件,也没有将当前活动作为Context
传递给任何内容。
最后,我在最近之前从未注意到这个错误,自从它首次创建以来唯一改变的是Android版本从某些风格 Jelly Bean 升级到 KitKat < / em>的
非常感谢任何帮助。谢谢!
答案 0 :(得分:1)
首先,在抛出OutOfMemoryError之前,我可以依赖未使用的活动进行垃圾回收吗?
尽管人们普遍认为,答案是否定的。您可以使用直到发生错误的活动来填充内存,Android既不会在后台堆栈中destroy any activities也不会在GC期间收集这些活动。
系统有一个选项可以完成后台堆栈中的活动,但它在2011年被禁用。现在,如果系统内存不足,Android将会终止整个过程。前台应用程序最有可能达到每个应用程序堆的限制,因为系统可以避免杀死它,并且可能有足够的空闲内存供其他人使用。
为什么活动不是GC?所有正在运行的活动都存储在ActivityThread类中(它执行与系统的所有交互并处理活动的生命周期事件),因此它们不符合垃圾回收的条件。它们只是在被摧毁后被从这里移除。
其次,Dalvik垃圾收集器可以收集循环引用吗?
是的,它可以像常规JVM的垃圾收集器一样。否则它将不兼容Java。
您可以使用Memory Analyzer tool and other techniques检查所有内存的去向。这些工具可以显示堆上的对象以及阻止它们被收集的内容。
我建议您在单个Activity中使用Fragments而不是多个Activity。片段具有回调,当片段离开scree(到后台堆栈)时,可以使用回调来释放视图层次结构。