指针和垃圾收集

时间:2012-09-14 09:57:15

标签: java android pointers memory-management garbage-collection

我有以下代码:

loadedImageDraggable.setBitmap(bitmap);
Log.v(TAG, "recycled image1 :"+bitmap);
Log.v(TAG, "recycled image2 :"+loadedImageDraggable.getBitmap());
bitmap.recycle();
bitmap = null;
Log.v(TAG, "recycled image3 :"+bitmap);
Log.v(TAG, "recycled image4 :"+loadedImageDraggable.getBitmap());

所以我在编码时的预期是,位图对象将从内存中删除。我实际得到的,当我运行代码时,这个日志跟踪:

recycled image1 :android.graphics.Bitmap@41afa8e0
recycled image2 :android.graphics.Bitmap@41afa8e0
recycled image3 :null
recycled image4 :android.graphics.Bitmap@41afa8e0

你可以在最后一行看到,仍然有这个位图对象,包装在loadedImageDraggable中。由于对象通过引用传递给方法,我希望java在对象设置为null时清理对该位图对象的所有引用。 我很迷惑 :/ 有人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

您有两个对同一位图对象的引用。一个是bitmap,另一个是loadedImageDraggable 现在,如果将bitmap设置为null,则loadedImageDraggable内的引用当然不会更改。它仍然指向你的Bitmap @ 41afa8e0

答案 1 :(得分:1)

在进一步解释之前,我想概述一下回收的工作原理。

这是定义,

public void recycle() 自:API级别1 bitmap.recycle() 释放与此位图关联的本机对象,并清除对像素数据的引用。这不会同步释放像素数据;如果没有其他引用,它只是允许它被垃圾收集。位图标记为“dead”,这意味着如果调用 getPixels()或setPixels(),它将抛出异常,并且不会绘制任何内容。此操作无法撤消,因此只有在您确定位图没有进一步用途时才应调用此操作。这是一个高级调用,通常不需要调用,因为正常的GC进程将在没有更多对此位图的引用时释放此内存。

在你的情况下,你仍然持有对位图对象的引用..但是调用了bitmap drawable DEAD。

当您通过setBitmap(null)取消loadedImageDraggable时。它将符合GC的条件。

即便如此,GC操作依赖于几种情况,其中一种是资源饥饿。在此之前,你永远不会知道它会被收集。希望这能让你更好地理解。