在原地复制位图是否会导致内存泄漏?

3
我很好奇以下代码是否会泄漏…
    data = getBitmapdataFromCameraCallback();//this is immutable, so...
    //make a mutable copy...
    originalUserPhoto = BitmapFactory.decodeByteArray(data, 0, data.length).copy(Config.ARGB_8888, true);

    Matrix matrix = new Matrix();
    // -1 doesn't reverse it for some oddball reason, so, we get REALLY close to -1
    matrix.preScale(-0.999f, 1.0f);//don't ask don't tell

     originalUserPhoto = Bitmap.createBitmap(originalUserPhoto, 0, 0,
          originalUserPhoto.getWidth(), originalUserPhoto.getHeight(),    
          matrix, true);

如果我在原地修改originalUserPhoto(请注意我将其作为createBitmap的源参数传递),那么这样会泄露原始数据吗?或者JVM足够智能以释放原来存在的数据?

1个回答

3
是和不是。你有两个Bitmap对象(第一个是通过decodeByteArray创建的,第二个是通过createBitmap创建的),第一个没有任何引用它的东西,所以在未来的垃圾回收周期中,它很可能会被删除。
话虽如此,当Bitmap被回收时,位图的本地支持存储也将被删除,但我建议在使用完第一个位图后手动删除它 - 将其保留在单独的引用中,并调用recycle()。位图可能非常昂贵。
顺便说一下,如果您的createBitmap的目的只是缩放,我建议在解码时通过传递选项将原始位图缩小。您将无法按照您想要的大小进行缩放,但至少您不会得到一个笨重的巨大位图,然后将其缩小到十分之一的大小。这将更快,避免内存飙升。

非常有趣...只是为了明确,你是说创建一个位图A的副本,使用位图A作为源,并将其输出到位图A,不会泄漏最初在位图A中的字节?还是说在这种情况下它不会,因为原始内容恰好是来自相机的字节数据,当所有对该数据的引用都消失时,相机将在本地释放它们?我的理解是,位图数据不会本地收集,除非你明确将其设置为空。 - Yevgeny Simkin
内存不会泄漏,Java 不会像 C++ 一样丢失指针跟踪。它将知道有两个位图对象,并最终删除被遗弃的那一个。这两个位图之间没有联系,你使用其中一个创建了另一个,但一旦创建过程完成,它们之间就没有任何链接,因此每个位图都有自己昂贵的内存块。 - EboMike
我不太同意。看看这个链接:http://developer.android.com/resources/articles/avoiding-memory-leaks.html 我之前也读过很多关于Bitmap需要手动释放以避免内存泄漏的文章...虽然它不像C语言那样,但它很相似(而且可以说更糟糕,因为没有什么方法可以强制释放内存! :) - Yevgeny Simkin
你误读了那篇文章。他们特别讨论的是仍然存在位图引用的情况。而在你的情况下,没有引用。在他们的情况下,这是由于static成员引起的,这意味着它将永久存在。 - EboMike
是的,我像狂人一样对所有东西进行回收。无论如何,感谢您的帮助...我会去其他地方寻找问题。 - Yevgeny Simkin
显示剩余2条评论

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