据我了解,使用bitmap = new WeakReference<Bitmap>
将允许GC为尽快收集bitmap
对象,但会设置bitmap
对象为null为bitmap = null
不一样的使用WeakReference
因为null
对象也由GC时收集它运行?WeakReference <object>和object = null之间是否有任何显着差异?
位图仅作为示例使用
据我了解,使用bitmap = new WeakReference<Bitmap>
将允许GC为尽快收集bitmap
对象,但会设置bitmap
对象为null为bitmap = null
不一样的使用WeakReference
因为null
对象也由GC时收集它运行?WeakReference <object>和object = null之间是否有任何显着差异?
位图仅作为示例使用
的区别在于WeakReference
允许JVM(由GC)来决定何时有必要/适当打破链接。
在一个典型的使用案例中,您希望GC在开始耗尽可用内存时断开链接,但之前没有。你的目标是将内容缓存在内存中,如有必要可以重新计算,重新载入等等。
如果您试图“手动”实施这种行为(通过指定null
来打破链接),您将遇到问题。例如,没有可靠的用于在JVM内存不足时通知应用程序代码的方式。
Grabage收集器不会收集任何对象,只要它具有一个或多个与其关联的强引用即可。
因此,例如,如果您对AsyncTask
的Activity
持有强烈的引用,它将导致内存泄漏,其中GC不会垃圾收集活动对象。
WeakReference
到Activity
确保AsyncTask
不会阻止Activity
及其引用的任何内容被垃圾收集。所以如果一个活动有0个强大的参考和一个或多个WeakReferencds
,它仍然可以被垃圾收集。
如果您明确地设置bitmap=null
,它可以避免不必要的引用,但您需要知道您的代码状态以及何时将其设置为null
。
弱引用意味着对象消耗堆内存,而不是从较长时间使用。在弱引用情况下,JVM将允许GC收集位图对象,即使JVM需要内存时位图对象不为null。
在赋值的情况下(bitmap = null),JVM将允许GC尽快收集位图对象。
嗯,我在前段时间旋转位图时使用了WeakReference
。在做低功率手机时,我得到了OutOfMemoryError
。
想这样,你实际上需要等待Bitmap.createScaledBitmap
方法来完成它的工作分配一个null。但方法是持有位图的参考,并且在此期间不需要使用您的位图,并且GC可能需要清理某些内存。
/**
* Returns an immutable bitmap from subset of the source bitmap,
* transformed by the optional matrix. The new bitmap may be the
* same object as source, or a copy may have been made. It is
* initialized with the same density as the original bitmap.
*
* If the source bitmap is immutable and the requested subset is the
* same as the source bitmap itself, then the source bitmap is
* returned and no new bitmap is created.
*
* @param source The bitmap we are subsetting
* @param x The x coordinate of the first pixel in source
* @param y The y coordinate of the first pixel in source
* @param width The number of pixels in each row
* @param height The number of rows
* @param m Optional matrix to be applied to the pixels
* @param filter true if the source should be filtered.
* Only applies if the matrix contains more than just
* translation.
* @return A bitmap that represents the specified subset of source
* @throws IllegalArgumentException if the x, y, width, height values are
* outside of the dimensions of the source bitmap, or width is <= 0,
* or height is <= 0
*/
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
Matrix m, boolean filter) {
checkXYSign(x, y);
checkWidthHeight(width, height);
if (x + width > source.getWidth()) {
throw new IllegalArgumentException("x + width must be <= bitmap.width()");
}
if (y + height > source.getHeight()) {
throw new IllegalArgumentException("y + height must be <= bitmap.height()");
}
// check if we can just return our argument unchanged
if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&
height == source.getHeight() && (m == null || m.isIdentity())) {
return source;
}
int neww = width;
int newh = height;
Canvas canvas = new Canvas();
Bitmap bitmap;
Paint paint;
Rect srcR = new Rect(x, y, x + width, y + height);
RectF dstR = new RectF(0, 0, width, height);
Config newConfig = Config.ARGB_8888;
final Config config = source.getConfig();
// GIF files generate null configs, assume ARGB_8888
if (config != null) {
switch (config) {
case RGB_565:
newConfig = Config.RGB_565;
break;
case ALPHA_8:
newConfig = Config.ALPHA_8;
break;
//noinspection deprecation
case ARGB_4444:
case ARGB_8888:
default:
newConfig = Config.ARGB_8888;
break;
}
}
if (m == null || m.isIdentity()) {
bitmap = createBitmap(neww, newh, newConfig, source.hasAlpha());
paint = null; // not needed
} else {
final boolean transformed = !m.rectStaysRect();
RectF deviceR = new RectF();
m.mapRect(deviceR, dstR);
neww = Math.round(deviceR.width());
newh = Math.round(deviceR.height());
bitmap = createBitmap(neww, newh, transformed ? Config.ARGB_8888 : newConfig,
transformed || source.hasAlpha());
canvas.translate(-deviceR.left, -deviceR.top);
canvas.concat(m);
paint = new Paint();
paint.setFilterBitmap(filter);
if (transformed) {
paint.setAntiAlias(true);
}
}
// The new bitmap was created from a known bitmap source so assume that
// they use the same density
bitmap.mDensity = source.mDensity;
bitmap.setHasAlpha(source.hasAlpha());
bitmap.setPremultiplied(source.mRequestPremultiplied);
canvas.setBitmap(bitmap);
canvas.drawBitmap(source, srcR, dstR, paint);
canvas.setBitmap(null);
return bitmap;
}
使用WeakReference
允许,如果系统需要空间,而这一切正在运行GC来收集你的源位图。另外,请检查Does assigning objects to null in Java impact garbage collection?。
如果GC实际发生,那么弱引用仅会丢失引用。设置为null是无条件的。 – EJP
位图ref变量创建对BitMap对象的弱引用...您不需要明确地说出bitmap = null。因此,如果同一个BitMap对象没有在应用程序中使用的位置,那么您已经创建了对BitMap对象的弱引用,那么JVM将认为GC是BitMap对象。换句话说,如果您创建了对BitMap对象的强引用并将其分配给位图var,则GC不会将BitMap对象视为GC。 –