当我尝试加载大小接近应用程序堆最大大小的图像时,我的应用程序崩溃了。我第一次加载图像时很好,然后我删除了对 Bitmap 对象的引用,并在我调用 mBitmap.recycle() //nativeRecycle 的地方完成了它。显然内存使用减少了,但是当我尝试再次加载图像时,我得到了 OutOfMemory 的崩溃。有趣的是,如果我在删除引用的同一个类中调用回收,似乎内存被释放,我可以再次加载图像。所以基本上,如果我直接调用 mBitmap.recycle() 与将 mBitmap.recycle() 放在引用位图的对象的最终确定中,我会得到不同的结果。知道为什么会这样吗?
问问题
690 次
1 回答
1
如果您接近使用堆的最大大小,那么您可能只是走运(或不走运)。直接调用 recycle() 与从终结器调用它可能会以您看到差异的方式改变 GC 的时间和行为。
在您尝试重新分配位图之前,您确定您的终结器(和 recycle())被调用了吗?终结器是不可靠的,可以无限期推迟。即使您当前在测试期间看到在重新分配之前调用了终结器,也不能保证这种情况总是会发生(尤其是对于不同的堆状态或未来/不同版本的 Dalvik)。
如果可以,请尽可能从终结器外部调用 recycle()。如果您知道何时完成,只需调用该方法;否则考虑使用 ReferenceQueue ( https://stackoverflow.com/a/10879076/150001 )。
自从我查看 Dalvik 已经有一段时间了,但我似乎记得位图缓冲区可能需要几个 GC 周期才能被清理,因为 VM 需要确保没有本地代码有任何剩余的指针指向它。因此,缓冲区可能不会在您期望的时候完全释放。
堆碎片也有可能导致问题,尽管很有可能使用 mmap() 分配大缓冲区并且不会导致碎片(再次,取决于当前版本的 Dalvik)。
于 2013-03-09T19:38:02.530 回答