Android应用程序内存不足问题-尝试了所有方法,但仍然不知所措

Android应用程序内存不足问题-尝试了所有方法,但仍然不知所措,android,android-activity,lifecycle,out-of-memory,Android,Android Activity,Lifecycle,Out Of Memory,我花了整整4天的时间尽我所能找出我正在开发的一个应用程序中的内存泄漏,但事情很久以前就没有意义了 我正在开发的应用程序是社交性质的,所以请考虑活动简介(p),并用数据列出活动-例如徽章(B)。您可以从配置文件跳到徽章列表、其他配置文件、其他列表等 因此,想象一个像P1->B1->P2->B2->P3->B3这样的流程。为了保持一致性,我加载的是同一用户的配置文件和徽章,因此每个p页面和每个B页面都是相同的 问题的要点是:导航一段时间后,根据每个页面的大小,我在随机位置(位图、字符串等)出现内存不

我花了整整4天的时间尽我所能找出我正在开发的一个应用程序中的内存泄漏,但事情很久以前就没有意义了

我正在开发的应用程序是社交性质的,所以请考虑活动简介(p),并用数据列出活动-例如徽章(B)。您可以从配置文件跳到徽章列表、其他配置文件、其他列表等

因此,想象一个像P1->B1->P2->B2->P3->B3这样的流程。为了保持一致性,我加载的是同一用户的配置文件和徽章,因此每个p页面和每个B页面都是相同的

问题的要点是:导航一段时间后,根据每个页面的大小,我在随机位置(位图、字符串等)出现内存不足异常,这似乎不一致

在做了所有可以想象的事情来找出为什么我的内存不足之后,我什么也没想到。我不明白的是,如果加载时内存不足而崩溃,为什么Android不会杀死P1、B1等。如果我通过onCreate()和onRestoreInstanceState()返回到它们,我希望这些早期的活动会死灰复燃

更不用说这个了——即使我做了P1->B1->Back->B1->Back->B1,我仍然会崩溃。这表明存在某种内存泄漏,但即使在转储hprof并使用MAT和JProfiler之后,我也无法确定它

我已经禁用了从web加载图像(并增加了加载的测试数据,以弥补这一点,并使测试公平),并确保图像缓存使用软引用。Android实际上试图释放它仅有的几个软引用,但就在它内存崩溃之前

Badge pages从web获取数据,从BaseAdapter将其加载到EntityData数组中,并将其馈送到ListView(我实际上使用的是Commonware,但在这个Badge活动中,实际上只有一个适配器,但我想以任何一种方式提及这一事实)

我已经检查了代码,没有找到任何可能泄漏的内容。我清除了所有我能找到的东西,甚至清除了System.gc()左右,但应用程序仍然崩溃

我仍然不明白为什么堆栈上的非活动没有收获,我真的很想弄清楚这一点。

在这一点上,我正在寻找任何提示、建议和解决方案。。。任何有帮助的


谢谢。

所以我唯一能想到的是,如果你有一个直接或间接引用上下文的静态变量。甚至是对部分应用程序的引用。我肯定您已经尝试过了,但我建议您这样做,以防万一,尝试在onDestroy()中清空所有静态变量,以确保垃圾回收器得到它

您是否持有对每个活动的引用?这是阻止Android从堆栈中删除活动的原因


我们可以在其他设备上重现此错误吗?根据ROM和/或硬件制造商的不同,我曾经体验过一些android设备的奇怪行为

我发现的最大的内存泄漏源是由对上下文的全局、高级别或长期引用引起的。如果将“上下文”存储在变量中的任何位置,可能会遇到不可预测的内存泄漏。

我认为问题可能是答案中所述的许多因素的组合造成的。就像@Tim所说的,对活动或该活动中的元素的(静态)引用可能会导致GC跳过该活动。这篇文章是在讨论这个方面。我认为可能的问题来自将活动保持在“可见流程”状态或更高的状态,这将保证活动及其相关资源永远不会被回收

前一段时间,我在一个服务中遇到了相反的问题,这就是我产生这种想法的原因:有一些东西使您的活动在流程优先级列表中保持较高的位置,这样它就不会受到系统GC的影响,例如引用(@Tim)或循环(@Alvaro)。循环不需要是无止境的或长时间运行的项目,只需要像递归方法或级联循环那样运行的项目(或沿着这些路线运行的项目)

编辑:据我所知,安卓会根据需要自动调用onPause和onStop。这些方法主要是为您提供overide,以便您可以在宿主进程停止之前(保存变量、手动保存状态等)处理所需的内容;但请注意,有明确规定,在任何情况下都不能调用onStop(以及onDestroy)。此外,如果托管进程同时托管具有“放弃”或“可见”状态的活动、服务等,则操作系统甚至可能不考虑停止进程/线程。例如:一个活动和一个服务都在同一个进程中被锁定,并且该服务从
onStartCommand()
返回
START\u STICKY
。该进程至少自动处于可见状态。这可能是这里的关键,尝试为活动声明一个新的proc,看看这是否会改变什么。尝试将此行添加到清单中的活动声明中,作为:
android:process=“:proc2”
,然后如果您的活动与其他任何活动共享一个进程,则再次运行测试。这里的想法是,如果你已经清理了你的活动,并且非常确定问题不是你的活动,那么其他的事情就是问题,是时候去寻找它了

此外,我不记得在哪里看到过它(如果我在Android文档中看到过的话),但我记得关于
pendingent
引用活动可能会导致活动出现这种行为

onStartCommand()
页面的链接,其中包含有关非杀戮过程的一些细节
Drawable d = imageView.getDrawable();  
if (d != null) d.setCallback(null);  
imageView.setImageDrawable(null);  
imageView.setBackgroundDrawable(null);