2012-09-14 139 views
2

我有以下代码:指针和垃圾收集

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 :[email protected] 
recycled image2 :[email protected] 
recycled image3 :null 
recycled image4 :[email protected] 

您可以在最后一行看到,仍然有此位图对象周围,包裹在loadedImageDraggable。由于对象是通过引用传递给方法的,我期望java在对象被设置为null时清除对该位图对象的所有引用。 我很困惑:/ 有人可以帮我解决这个问题吗?

+0

这是'loadedImageDragable'类吗?无论如何,它可能不是它的主要实例,而是一个副本。 – SJuan76

+0

no-在该类中没有位图复制操作。内部Bitmap属性只有一个getter和setter。 – stoefln

回答

1

在进一步解释之前,我想给你一个概述回收工作的一般概述。

下面是定义,

公共无效再循环() 自:API级别1 bitmap.recycle() 免与该位图相关联的原生对象,并清除参考像素数据。这不会同步释放像素数据;它只是允许它被垃圾收集,如果没有其他引用。位图被标记为“死”,这意味着它将抛出一个异常,如果getPixels()或setPixels()被调用,并且不会画任何东西。这个操作不能颠倒过来,所以只有在你确定没有进一步的位图使用时才应该调用它。这是一个高级调用,通常不需要调用,因为当没有更多的位图引用时,普通的GC进程将释放该内存。

在你的情况下,你仍然持有对位图对象的引用..但调用了使位图可绘制DEAD。

当您通过setBitmap(null)使您的loadedImageDraggable无效时。它将有资格获得GC。

即使GC操作依赖于几个条件,其中一个是资源饥饿。在那之前你永远不知道它会被收集。希望这会给你一个更好的理解。

+0

谢谢 - 有没有办法确保每个参考被删除?我的意思是让我说我​​有20个对象使用这一个图像,我真的必须手动跟踪它们并将每个指针设置为null吗? – stoefln

+0

是的,使用'finalize(){// Release here}'或'try-fianlly {// Release here}'会让你的代码更加一致。 –

2

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

+0

谢谢,有没有办法确保每个参考被删除?我的意思是让我说我​​有20个使用该图像的对象,我真的必须手动跟踪它们并将每个指针设置为null吗? – stoefln