2017-06-05 20 views
-1

私はそれを理解し、bitmap = new WeakReference<Bitmap>を使用すると、GCはできるだけ早くbitmapオブジェクトを収集することができますが、bitmap = nullWeakReferencenull以来のオブジェクトも時にGCによって収集され使用するのと同じではないとnullにbitmapオブジェクトを設定しますそれは実行されますか?WeakReference <object>とobject = nullに大きな違いはありますか?

ビットマップは、例としてのみ使用さ

+0

弱参照は、GCが実際に発生した場合にのみ参照を失います。nullへの設定は無条件です。 – EJP

+0

bitmap ref変数はBitMapオブジェクトへの弱い参照を作成します...あなたは明示的にbitmap = nullと言う必要はありません。したがって、同じBitMapオブジェクトにurアプリケーションで使用されている場所がない場合、JVMはBitMapオブジェクトをGCに考えると、BitMapオブジェクトへの弱い参照を作成しています。他の方法では、BitMapオブジェクトへの強い参照を作成し、ビットマップvarに割り当てた場合、GCはBitMapオブジェクトをGCには考慮しません。 –

答えて

1

差がWeakReferenceは、リンクを解除するために、適切な/必要である場合、JVM(GC)を決定することを可能にすることです。

一般的な使用例では、GCが空きメモリが不足し始めたときにGCをリンクしてから切断するようにします。目標は、必要に応じて再計算、再ロードなどが可能な、メモリ内のものをキャッシュすることです。

"手動で"このような種類の動作を実装しようとした場合(リンクを中断するためにnullを割り当てる)、問題が発生します。たとえば、信頼できる JVMのメモリ不足時にアプリケーションコードを通知する方法はありません。

1

グラバーコレクターは、1つ以上の強い参照が関連付けられている限り、オブジェクトを収集しません。

たとえば、Activityへの強い参照をAsyncTaskから保持している場合、アクティビティオブジェクトがGCによってガベージコレクションされないメモリリークが発生します。

WeakReferenceからActivityまでは、AsyncTaskActivityとそれが参照するものがガベージコレクションから保護されないようにします。そのため、アクティビティに0の強い参照と1つ以上のWeakReferencdsがある場合、それはまだガベージコレクションされます。

bitmap=nullを明示的に設定している場合は、不要な参照の保持を避けることができますが、コードの状態といつnullに設定するかを意識する必要があります。

1

弱い参照は、オブジェクトがヒープメモリを消費し、長い時間使用されないことを意味します。弱参照の場合、JVMはメモリが必要なときにビットマップオブジェクトがヌルでなくても、GCがビットマップオブジェクトを収集できるようにします。

割り当て(bitmap = null)の場合、JVMはGCができるだけ早くビットマップオブジェクトを収集できるようにします。

1

まあ、少し前にビットマップを回転していたときは、WeakReferenceを使用しました。それをやっている間私は低仕様の携帯電話でOutOfMemoryErrorを得ていた。

このように考えると、実際にはnullを割り当てるジョブを終了するには、Bitmap.createScaledBitmapメソッドを待つ必要があります。しかし、メソッドがビットマップの参照を保持しているので、この時間にビットマップを使用する必要はなく、GCはメモリの一部をクリーンアップする必要があります。 WeakReferenceを使用して

/** 
* 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; 
} 

は、このすべての実行中にシステムがスペースを必要とする場合、GCはあなたのソースビットマップを収集することができます。また、Does assigning objects to null in Java impact garbage collection?をチェックしてください。

関連する問題