屏幕旋转导致内存泄漏问题

3
我写了一个标准的Android应用程序,在GridView中显示一堆照片(从联系人获取)。该应用程序在屏幕方向更改时没有做任何特殊处理来保留数据,只是在Activity重新创建时重新创建GridView、适配器和加载器。
然而,在几次方向更改后,应用程序变慢了;在更多方向更改后,它会崩溃并出现内存不足错误(在BitmapFactory.decodeStream()处)。如果我让垃圾收集器运行一段时间来让它执行其任务,离开它在旋转之间停留一分钟,这种情况仍会发生。
我原以为当Activity在方向更改期间被销毁时,Android会释放与Activity相关联的所有内存。然而,事实似乎并非如此。我的问题是:即使Activity被销毁,我可能会无意中保留哪些内存?
(请注意,只要不经过太多次的方向更改,应用程序就可以正常运行,因此我正在使用的内存最小化方法是足够的。)

通常,这是由于使用静态引用位图或将活动上下文传递给保留对其的引用的其他类所致。您是否做了类似的事情?发布onCreate()和onResume()会有所帮助。MAT将向您显示未被收集的内容。附注:垃圾回收运行得很好。 - Simon
看看这个和我关于unbind drawable的答案。https://dev59.com/7WUq5IYBdhLWcg3wJM9A#14759756 - Simon
@Simon:谢谢!我认为你是对的:我正在使用非静态内部类作为ViewHolder,就像http://developer.android.com/training/contacts-provider/display-contact-badge.html中所述。然而,现在我明白了,其中的视图将保留对上下文的引用。我将尝试将其重构为静态内部类,看看会发生什么。我还研究了我的onCreate和onResume,但我不认为那里有任何有趣的东西。如果我知道如何在onDestroy期间轻松提取GridView中的屏幕位图,我将显式解除绑定它们。 - Peter McLennan
1个回答

1

我认为你忘记了添加 bitmap.recycle();

另外,解决这个问题的简单方法是,在AndroidManifest中的activity参数中添加:android:configChanges="orientation|screenSize"


这个黑客技巧,即使是 Google 也说应该只在最后情况下使用,它将如何修复内存泄漏问题? - Simon
活动将在比仅更改方向更多的情况下重新创建。所有这些只是隐藏了错误。您添加此内容,更改屏幕,它不会崩溃。但是错误仍然存在。现在尝试插入汽车停靠站,或将应用程序放在后台并接听电话,或更改区域等等。这是一种无法解决问题的黑客行为。 - Simon
为什么不试一下呢?运行你的应用程序,在onCreate()中设置一个断点。现在更改区域,会发生什么?然而,争论这个问题是毫无意义的。如果你想使用Google说不应该使用的黑客技术,那就随便你了。应用商店已经充斥着有这个漏洞的应用程序。 - Simon
2
我个人检查过,当调用时,onDestroyonCreate方法不会被调用。这不是一个黑客技巧,因为如果您的活动具有不同的布局,则无需使用此configChanges,如果只有一个布局,则此configChanges仅加速您的应用程序。 - artemiygrn
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/39625/discussion-between-kvirair-and-simon - artemiygrn
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接