【问题标题】:Pointers and garbage collection指针和垃圾收集
【发布时间】:2012-09-14 09:57:15
【问题描述】:

我有以下代码:

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 时清除对该位图对象的所有引用。 我很困惑 :/ 有人可以帮我解决这个问题吗?

【问题讨论】:

  • loadedImageDragable 属于哪个类?无论如何,它可能不是返回它的主实例而是一个副本。
  • no- 类中没有位图复制操作。内部 Bitmap 属性只有一个 getter 和一个 setter。

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


【解决方案1】:

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

【讨论】:

  • 谢谢-有没有办法确保每个引用都被删除?我的意思是说我有 20 个使用该图像的对象,我真的必须手动跟踪它们并将每个指针设置为空吗?
【解决方案2】:

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

这是定义,

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

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

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

即使这样,GC 操作也取决于几个条件,其中之一就是资源匮乏。在那之前,你永远不知道它会被收集。希望这能让您更好地理解。

【讨论】:

  • 谢谢-有没有办法确保每个引用都被删除?我的意思是说我有 20 个对象使用那张图片,我真的必须手动跟踪它们并将每个指针设置为空吗?
  • 是的,使用finalize(){// Release here}try-fianlly{// Release here} 会使您的代码更加一致。
猜你喜欢
  • 2012-10-03
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
  • 2012-03-21
  • 2013-01-15
相关资源
最近更新 更多