退出时清理程序并处理GC

时间:2011-01-08 00:15:10

标签: java android memory memory-management

我正在编写一个涉及大量图像的程序,每个屏幕密度超过100个。幸运的是,它们在空间方面并不是很大。在任何给定时间我大约使用11。我还在每个看起来占用大量内存的图像上使用函数Bitmap.createScaledBitmap

到目前为止,在调试这个应用程序时,我似乎能够无限期地使用它而不会遇到内存问题,我希望这意味着我不会泄漏内存。

然而,我注意到的一件事是,如果我通过后退按钮“退出”我的应用程序(我没有在后台运行任何东西),然后不久后重新启动应用程序,我有时会出来调用Bitmap.createScaledBitmap

时的内存错误
01-07 19:01:24.935: ERROR/AndroidRuntime(27419): java.lang.OutOfMemoryError: bitmap size exceeds VM budget

基本上我的问题是,我在这里做错了什么?当用户按下后退按钮时,我是否需要清理自己的垃圾?我原以为当按下后退按钮并且活动被破坏时,GC会自动处理这个问题。这让我相信我做了别的错事,比如内存泄漏。但后来我回到了这样的事实:我的应用程序可以在20分钟内使用大量内存,但是在重启后5秒内自杀,这让我感到困惑。

谢谢大家。

编辑:我实施了几个快速而肮脏的修复。

首先我尝试了这个,并且很难让应用程序强行关闭。

@Override
public void onBackPressed() {
    finish();
}

接下来,我尝试将其与onBackPressed结合使用,我无法再复制我的问题了。请注意,方法调用只是一个基本上执行allImages = null;

的循环
protected void onStop () {
    super.onStop();
    mComponent.releaseImages();
}

此时看来,在调用finish()之后,活动内存中仍有对象。相当奇怪。

3 个答案:

答案 0 :(得分:3)

也许你对应用程序的android生命周期有所了解。按后退按钮不会杀死您的java程序。因此,再次启动您的应用程序会启动一个新的应用程序。

请参阅http://developer.android.com/guide/topics/fundamentals.html#actlife

例如,如果您在onStart()中创建图像但不在onStop()中删除它们,则仍然可以引用图像。每次都会增加更多内存。

答案 1 :(得分:2)

1:当onResume()恢复您的应用程序时,您的先前Bitmap个对象将再次加载。 需要确保您不再分配所有Bitmap个对象。

2:导致这些错误的内存泄漏经常发生。当您的应用程序恢复时,Bitmap对象仍然会引用其初始化状态。 可以使用特定模式来阻止重新分配相同的Bitmap个对象。此模式称为Memory Pools,它可以防止内存的碎片

想到碎片,就像这样:你正试图停车。一个愚蠢的人类向右停放了一点点,而另一个愚蠢的人类向左停放了一点点。那个插槽是碎片化的。最初你应该有足够的空间将车停在那个地方,但停车区本身现在已经碎片化了。您的车没有空插槽 - 停车区域内存

要防止出现这种情况,您可以使用Memory Pools模式。

通过使用此模式,您可以:

  • 设置最大值Bitmap 您将在期间使用的对象 应用程序的生命周期。
  • 在您的申请恢复后请求空位,然后重新初始化您的申请 Bitmap个对象,而不是重新分配它们。

通过使用此模式,您需要确保:

  • 您有足够的空间容纳特定池中的Bitmap个对象。

然而,第二部分的解决方案根本没有必要(嘿,这是一个很好的工具)。

简短解决方案:当您在内存中仍有旧的Bitmap引用时,恢复应用程序时,无法创建相同数量的Bitmap个对象。检查您的应用程序恢复后是否已加载Bitmap个对象,如果不加载,请创建它们。

答案 2 :(得分:-1)