bumptech / bumptech/glide

Looping animated GIFs leads to lots of garbage generation per frame

Open
#442 7 comments 0 reactions 0 assignees View on GitHub
enhancement GIF
Dominant language
Java
Stars
35k
Forks
6.2k
Avg merge
1d 11h
Merged PRs (30d)
8

Description

In my app I get a GifDrawable from GifDrawableLoadProvider by giving it a file path. The animation then does the invalidate->draw loop until the back button is pressed.

If I watch the Android Studio memory monitor window, I see the Allocation size steadily increasing. If I grab an allocation tracker dump, I see this pattern repeat every frame:

| Type | length of byte[] |
| --- | --- |
| com.bumptech.glide.load.engine.Engine$LoadStatus | 16 |
| java.util.concurrent.Executors$RunnableAdapter | 16 |
| com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$LoadTask | 48 |
| java.lang.Object[] | 64 |
| java.util.HashMap$HashMapEntry | 32 |
| com.bumptech.glide.load.engine.EngineRunnable | 32 |
| com.bumptech.glide.load.engine.DecodeJob | 64 |
| java.util.ArrayList | 32 |
| com.bumptech.glide.load.engine.EngineJob | 80 |
| com.bumptech.glide.load.engine.EngineKey | 64 |
| com.bumptech.glide.load.resource.gif.GifFrameModelLoader$GifFrameDataFetcher | 16 |
| java.util.WeakHashMap$Entry | 48 |
| java.lang.String | 32 |
| char[] | 48 |
| com.bumptech.glide.request.GenericRequest | 128 |
| java.util.UUID | 64 |
| byte[] | 32 |
| com.bumptech.glide.load.resource.gif.GifFrameLoader$FrameSignature | 16 |
| com.bumptech.glide.load.resource.gif.GifFrameLoader$DelayTarget | 48 |

That's 880 bytes from within each call to GifFrameLoader.loadNextFrame.

One bit of low hanging fruit seems to be the construction of a new GenericRequest object each time (208 bytes). The pool is consulted but is always empty, because rather than recycle these objects, they are cleared and disposed of in GifFrameLoader.FrameLoaderCallback's MSG_CLEAR branch.

Another big block comes from onSizeReady, which allocates 464 bytes in small objects each time as well.

Ideally, an Animated GIF could be played forever with no per-frame draw calls, though I understand that sometimes there are required.

Contributor guide

Open the contributing guide

Research direction

Start at GifFrameLoader.loadNextFrame and trace the per-frame allocations listed in the report, especially GenericRequest creation, onSizeReady, and FrameLoaderCallback's MSG_CLEAR branch. Compare the allocation tracker output before and after changes while looping an Animated GIF; done means substantially reducing avoidable per-frame garbage without breaking playback.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
mobile-dev, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.