Java 在退出时清理程序并处理GC

Java 在退出时清理程序并处理GC,java,android,memory,memory-management,Java,Android,Memory,Memory Management,我正在写一个程序,它包含大量的图像,每个屏幕的密度超过100。幸运的是,它们在空间上不是很大。我在任何给定的时间使用大约11。我还在每个图像上使用函数Bitmap.createScaledBitmap,这似乎占用了很多内存 到目前为止,在调试这个应用程序时,我似乎能够无限期地使用它,而不会遇到内存问题,我希望这意味着我没有泄漏内存 然而,我注意到的一件事是,如果我通过后退按钮“退出”我的应用程序(我没有在后台运行任何东西),然后很快重新启动应用程序,我有时会在调用Bitmap.createSca

我正在写一个程序,它包含大量的图像,每个屏幕的密度超过100。幸运的是,它们在空间上不是很大。我在任何给定的时间使用大约11。我还在每个图像上使用函数
Bitmap.createScaledBitmap
,这似乎占用了很多内存

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

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

01-07 19:01:24.935: ERROR/AndroidRuntime(27419): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
所以基本上我的问题是,我做错了什么?我是否需要清理自己的垃圾,比如在onDestroy中,当用户按下后退按钮时?我原以为当按下后退按钮并且活动被破坏时,GC会自动处理这个问题。这让我相信我做错了别的事情,比如内存泄漏。但后来我又回到了一个事实:我的应用程序可以在20分钟内占用大量内存,但在重启后的5秒钟内就会自动消失,这让我感到困惑

谢谢大家

编辑:我实现了两个快速修复

首先,我尝试了这个方法,但很难让应用程序强制关闭

@Override
public void onBackPressed() {
    finish();
}
接下来,我尝试将此与onBackPressed结合使用,我无法再重复我的问题。注意,方法调用只是一个循环,基本上不执行
allImages=null

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

此时,似乎在调用finish()之后,内存中仍然有来自活动的对象。很奇怪。

也许你的应用程序的android生命周期有问题。按下后退按钮不会终止java程序。所以再次搜索你的应用程序确实会启动一个新的应用程序


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

1:当通过
onResume()
恢复应用程序时,将再次加载以前的
位图
对象需要确保不会再次分配所有
位图
对象

2:通常是内存泄漏导致了这些错误。当应用程序恢复时,
位图
对象仍有对其初始化状态的引用您可以使用特定的模式来防止重新分配相同的
位图
对象。这个模式被调用,它可以防止内存的碎片化

想象一下这样的碎片:你正试图停车。一个愚蠢的人向右停车太多,另一个愚蠢的人向左停车太多。这个位置是零碎的。本来你应该有足够的空间把车停在那个地方,但现在停车场本身已经支离破碎了。您的车没有空位了-停车场内存不足

为了防止出现这种情况,可以使用该模式

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

  • 设置位图的总最大值
    
    在测试期间将使用的对象
    应用程序的生命周期
  • 在应用程序恢复时请求一个空插槽,然后重新初始化应用程序
    位图
    对象,而不是重新分配它们
通过使用此模式,您需要确保:

  • 确保在特定池中有足够的空间放置
    位图
    对象
然而,第二部分的解决方案根本没有必要(嘿,这是一个很好的工具)


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

此问题归因于android的错误。有关此问题和一些解决方法的信息,请参阅以下链接


我的理解是,按下后退按钮确实会执行finish(),除非您选择重写该方法以执行不同的操作。在我的情况下,我没有覆盖任何东西,因此应该调用finish。如果我的应用程序有助于可视化,请将其视为单个活动应用程序。据我所知,按“上一步”按钮并立即再次启动应用程序将经历onStop()、onRestart()、onStart()。finish()是一个调用,如果您的活动完成,您可以调用自己。重要的是要记住,关闭/退出android应用程序并不一定会终止java进程。当应用程序再次启动时,它将被恢复。我希望能有更好的文档记录。Charlie Sheen写道:“当应用程序恢复时,检查是否已经加载位图对象,如果没有,请创建它们。”---这可能是最好的答案,我应该这样做,但上面提到的我的创可贴似乎已经奏效了。这些肮脏的小修补程序只是解决你具体问题的一个很短的方法。我宁愿用我在回答中提到的模式来解决这类问题。我喜欢人们把事情记下来而不提供理由/叹息