Java OutOfMemoryException在活动之间来回时出现异常,尽管回收了所有位图并收集了垃圾

Java OutOfMemoryException在活动之间来回时出现异常,尽管回收了所有位图并收集了垃圾,java,android,memory,bitmap,garbage-collection,Java,Android,Memory,Bitmap,Garbage Collection,这似乎是一个简单的问题,但我不知道是什么原因造成的 我有一个活动,它使用Bitmap.createBitmap(宽度、高度、配置)创建多个位图,将画布应用于这些位图,并在画布上绘制。完成后,我会回收它们。它们是在其显示的分辨率中创建的,并且没有任何问题被创建。在onsurfacedestromed()中,我循环使用每个位图。作为绘图说明的一部分,我会分配临时位图,一旦不需要它们,它们就会被回收。作为额外措施,我还将System.gc()放在每个活动的OnSurfaceDestroyed()中 现

这似乎是一个简单的问题,但我不知道是什么原因造成的

我有一个活动,它使用Bitmap.createBitmap(宽度、高度、配置)创建多个位图,将画布应用于这些位图,并在画布上绘制。完成后,我会回收它们。它们是在其显示的分辨率中创建的,并且没有任何问题被创建。在onsurfacedestromed()中,我循环使用每个位图。作为绘图说明的一部分,我会分配临时位图,一旦不需要它们,它们就会被回收。作为额外措施,我还将System.gc()放在每个活动的OnSurfaceDestroyed()中

现在,当我在这个活动和另一个活动(不创建位图)之间切换时,在来回切换大约6或7次之后,我会得到一个OutOfMemoryException。LogCat清楚地表明,每当我创建第一个活动时,自动垃圾收集器就会释放越来越多的空间。以下是源错误:

06-23 12:49:53.984: E/dalvikvm-heap(8487): Out of memory on a 1382416-byte allocation.
我意识到这是一个巨大的字节分配,但我真的不明白为什么?前5-6次都没有问题,那么为什么即使我在回收所有东西,记忆似乎也在积累呢?我相当确定我正在做的其他事情都不是高记忆

我确实找到了一种解决方法,使用Config.RGB_565而不是Config.ARGB_8888来创建位图,但这只是将来回的til崩溃计数从6-7增加到30左右。不知什么原因,它还在积累记忆

除了recycle()之外,还有什么我可以使用的,或者其他一些系统资源可以帮助我吗

前5-6次都没有问题,那么为什么即使我在回收所有东西,记忆似乎也在积累呢

它不会累积。它是碎片。在Java上,
OutOfMemoryError
相当直白:没有足够的堆空间来分配所需的块。在Android的Dalvik VM上,
OutOfMemoryError
实际上是
没有BlockBigenoughError
,因为Dalvik没有压缩垃圾收集器。我更深入地探讨了这意味着什么(以及新的艺术运行时应该在哪里产生影响)

除了recycle()之外,还有什么我可以使用的,或者其他一些系统资源可以帮助我吗

第1步:将您的
android:minSdkVersion
设置为11或更高


第二步:停止回收位图。使用
BitmapFactory.Options
上的
inBitmap
重用它们。维护您自己的可用
位图
对象池,这些对象可以根据您需要的每个图像分辨率进行回收。有关更多信息,请参阅。

我将尝试一下。谢谢。我基本上理解了文档中的内容,但有一点让人困惑:我是通过编程创建位图,而不是从文件中收集位图。文档指定您通过BitmapFactory,因为您需要获取inBitmap的选项。我是否需要在位图第一次创建后将其保存到文件中,然后以这种方式检索它们?似乎离我原来的位置还有一步之遥。我在最初的过程中从未使用过位图工厂。@JohnO.:“我是以编程方式创建位图,而不是从文件中收集它们”——因为我不知道这到底意味着什么,您可能希望编辑您的问题以解释如何创建和使用位图。即兴使用时,您应该仍然能够重用它们,但是,通过擦除它们的当前内容并绘制新内容,而不是每次都丢弃和重新实例化它们。我使用Bitmap.createBitmap(宽度、高度、配置)创建了几个位图,对它们应用画布,然后在画布上绘制。完成后,我会回收它们。我会一直查看文档和参考资料,直到找到一种方法来完成这项工作。@JohnO.:“一旦完成,我就回收它们”——在另一种情况下,如果需要相同大小的
位图,请重新使用它们。使用
eraseColor()
擦除当前内容(并放置所需背景),然后使用
画布再次渲染。只有当您确信在相当长的一段时间内(对于更大的分辨率,可能是“相当长的一段时间”=“从不”)不需要该分辨率的
位图的另一个实例时,才使用
recycle()