title: Glide Transformation memory leak
body: <p>I am facing this memory leak while using Glide. Here's the trace by LeakCanary.</p>
  
  <pre><code> D/LeakCanary: ├─ android.provider.FontsContract
   D/LeakCanary: │    Leaking: NO (HomeApplication↓ is not leaking and a class is never leaking)
   D/LeakCanary: │    GC Root: System class
   D/LeakCanary: │    ↓ static FontsContract.sContext
   D/LeakCanary: ├─  &lt;package&gt;.HomeApplication
   D/LeakCanary: │    Leaking: NO (Application is a singleton)
   D/LeakCanary: │    HomeApplication does not wrap an activity context
   D/LeakCanary: │    ↓ HomeApplication.mComponentCallbacks
   D/LeakCanary: │                      ~~~~~~~~~~~~~~~~~~~
   D/LeakCanary: ├─ java.util.ArrayList
   D/LeakCanary: │    Leaking: UNKNOWN
   D/LeakCanary: │    ↓ ArrayList.elementData
   D/LeakCanary: │                ~~~~~~~~~~~
   D/LeakCanary: ├─ java.lang.Object[]
   D/LeakCanary: │    Leaking: UNKNOWN
   D/LeakCanary: │    ↓ array Object[].[1]
   D/LeakCanary: │                     ~~~
   D/LeakCanary: ├─ com.bumptech.glide.Glide
   D/LeakCanary: │    Leaking: UNKNOWN
   D/LeakCanary: │    ↓ Glide.memoryCache
   D/LeakCanary: │            ~~~~~~~~~~~
   D/LeakCanary: ├─ com.bumptech.glide.load.engine.cache.LruResourceCache
   D/LeakCanary: │    Leaking: UNKNOWN
   D/LeakCanary: │    ↓ LruResourceCache.cache
   D/LeakCanary: │                       ~~~~~
   D/LeakCanary: ├─ java.util.LinkedHashMap
   D/LeakCanary: │    Leaking: UNKNOWN
   D/LeakCanary: │    ↓ LinkedHashMap.tail
   D/LeakCanary: │                    ~~~~
   D/LeakCanary: ├─ java.util.LinkedHashMap$LinkedHashMapEntry
   D/LeakCanary: │    Leaking: UNKNOWN
   D/LeakCanary: │    ↓ LinkedHashMap$LinkedHashMapEntry.key
   D/LeakCanary: │                                       ~~~
   D/LeakCanary: ├─ com.bumptech.glide.load.engine.EngineKey
   D/LeakCanary: │    Leaking: UNKNOWN
   D/LeakCanary: │    ↓ EngineKey.transformations
   D/LeakCanary: │                ~~~~~~~~~~~~~~~
   D/LeakCanary: ├─ com.bumptech.glide.util.CachedHashCodeArrayMap
   D/LeakCanary: │    Leaking: UNKNOWN
   D/LeakCanary: │    ↓ CachedHashCodeArrayMap.mArray
   D/LeakCanary: │                             ~~~~~~
   D/LeakCanary: ├─ java.lang.Object[]
   D/LeakCanary: │    Leaking: UNKNOWN
   D/LeakCanary: │    ↓ array Object[].[1]
   D/LeakCanary: │                     ~~~
   D/LeakCanary: ├─ &lt;package&gt;.&lt;some class&gt;$3
   D/LeakCanary: │    Leaking: UNKNOWN
   D/LeakCanary: │    Anonymous class implementing com.bumptech.glide.load.Transformation
   D/LeakCanary: │    ↓ &lt;some class&gt;$3.this$0
   D/LeakCanary: │                ~~~~~~
   D/LeakCanary: ├─ &lt;package&gt;.&lt;some class&gt;
   D/LeakCanary: │    Leaking: UNKNOWN
   D/LeakCanary: │    ↓ &lt;some class&gt;.activity
   D/LeakCanary: │              ~~~~~~~~
   D/LeakCanary: ╰→ &lt;package&gt;.&lt;some activity&gt;
   D/LeakCanary: ​     Leaking: YES (Activity#mDestroyed is true and ObjectWatcher was watching this)
   D/LeakCanary: ​     key = 632286af-8d9e-4b05-bc8f-5974ca16931b
   D/LeakCanary: ​     watchDurationMillis = 2957886
   D/LeakCanary: ​     retainedDurationMillis = 2952885
  </code></pre>
  
  <p>So this is saying that the transformation is cached by glide and that transformation references activity.
  I was under the impression the Glide is lifecycle aware but yeah I understand that it might apply only to load requests.
  So I was thinking about possible solutions that I have:</p>
  
  <ol>
  <li>don't reference activity in transformation code</li>
  <li>clear the glide's state so that it clears the transformation in cache. </li>
  <li>ask glide to not cache the transformation.</li>
  </ol>
  
  <p>What's the way to go from here?</p>
  
  <p>Also, is there something completely wrong that I am missing right now. Here's the transformation   code:</p>
  
  <pre><code>new Transformation&lt;Drawable&gt;() {
        @NonNull
        @Override
        public Resource&lt;Drawable&gt; transform(
            @NonNull Context context,
            @NonNull Resource&lt;Drawable&gt; resource,
            int outWidth,
            int outHeight) {
          Drawable albumArt = resource.get();
          int backgroundColor;
          if (albumArt instanceof BitmapDrawable) {
            backgroundColor =
                &lt;some util class&gt;.getBackgroundColorForBitmap(
                    ((BitmapDrawable) albumArt).getBitmap());
  
          } else {
            backgroundColor = defaultBackgroundScrimColor;
          }
          Drawable[] layers = {
            albumArt, &lt;some util class&gt;.getGradientOverlay(backgroundColor)
          };
          return new SimpleResource&lt;&gt;(new LayerDrawable(layers));
        }
  
        @Override
        public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {}
      };
    }
  
  </code></pre>
  
  <p>Also, I am still trying to find out how I am referencing activity in the transformation code.</p>