2017-06-05 52 views
-1

据我了解,使用bitmap = new WeakReference<Bitmap>将允许GC为尽快收集bitmap对象,但会设置bitmap对象为null为bitmap = null不一样的使用WeakReference因为null对象也由GC时收集它运行?WeakReference <object>和object = null之间是否有任何显着差异?

位图仅作为示例使用

+0

如果GC实际发生,那么弱引用仅会丢失引用。设置为null是无条件的。 – EJP

+0

位图ref变量创建对BitMap对象的弱引用...您不需要明确地说出bitmap = null。因此,如果同一个BitMap对象没有在应用程序中使用的位置,那么您已经创建了对BitMap对象的弱引用,那么JVM将认为GC是BitMap对象。换句话说,如果您创建了对BitMap对象的强引用并将其分配给位图var,则GC不会将BitMap对象视为GC。 –

回答

1

的区别在于WeakReference允许JVM(由GC)来决定何时有必要/适当打破链接。

在一个典型的使用案例中,您希望GC在开始耗尽可用内存时断开链接,但之前没有。你的目标是将内容缓存在内存中,如有必要可以重新计算,重新载入等等。

如果您试图“手动”实施这种行为(通过指定null来打破链接),您将遇到问题。例如,没有可靠的用于在JVM内存不足时通知应用程序代码的方式。

1

Grabage收集器不会收集任何对象,只要它具有一个或多个与其关联的强引用即可。

因此,例如,如果您对AsyncTaskActivity持有强烈的引用,它将导致内存泄漏,其中GC不会垃圾收集活动对象。

WeakReferenceActivity确保AsyncTask不会阻止Activity及其引用的任何内容被垃圾收集。所以如果一个活动有0个强大的参考和一个或多个WeakReferencds,它仍然可以被垃圾收集。

如果您明确地设置bitmap=null,它可以避免不必要的引用,但您需要知道您的代码状态以及何时将其设置为null

1

弱引用意味着对象消耗堆内存,而不是从较长时间使用。在弱引用情况下,JVM将允许GC收集位图对象,即使JVM需要内存时位图对象不为null。

在赋值的情况下(bitmap = null),JVM将允许GC尽快收集位图对象。

1

嗯,我在前段时间旋转位图时使用了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?

相关问题