facebook / fresco

An Android library for managing images and the memory they use.
https://frescolib.org/
MIT License
17.07k stars 3.75k forks source link

load animated webp with OOM #2631

Open xucongyinq opened 2 years ago

xucongyinq commented 2 years ago

We use GitHub Issues for bugs.

If you have a non-bug question, please ask on Stack Overflow: http://stackoverflow.com/questions/tagged/fresco

--- Please use this template, and delete everything above this line before submitting your issue ---

Description

I use fresco to load an animated webp with CACHING_STRATEGY_FRESCO_CACHE, then OOM happened

Reproduction

initialize fresco with ImagePipelineConfigInterface.getCloseableReferenceLeakTracker = { func isSet(): Boolean = true } , and build an DraweeController with new DrawableFactory with CACHING_STRATEGY_FRESCO_CACHE, like this:

class MultiDrawableFactory() : DrawableFactory {
    override fun supportsImageType(closeableImage: CloseableImage): Boolean {
        return closeableImage is CloseableAnimatedImage
    }

    override fun createDrawable(closeableImage: CloseableImage): Drawable? {
        val closeable = closeableImage as CloseableAnimatedImage
        return AnimatedDrawable2(createAnimationBackend(closeable.imageResult!!))
    }

    private fun createAnimationBackend(animatedImageResult: AnimatedImageResult): AnimationBackend {
        val animatedImage = animatedImageResult.image
        val animatedDrawableBackend: AnimatedDrawableBackend = AnimatedDrawableBackendImpl(
            AnimatedDrawableUtil(),
            animatedImageResult,
            Rect(0, 0, animatedImage.width, animatedImage.height),
            false
        )
        val bitmapFrameCache: BitmapFrameCache = FrescoFrameCache(
            AnimatedFrameCache(AnimationFrameCacheKey(animatedImageResult.hashCode()), ImagePipelineFactory.getInstance().bitmapCountingMemoryCache),
            true
        )

        //val bitmapFrameCache = Cache()
        val bitmapFrameRenderer: BitmapFrameRenderer = AnimatedDrawableBackendFrameRenderer(
            bitmapFrameCache,
            animatedDrawableBackend
        )
        val bitmapFramePreparer = DefaultBitmapFramePreparer(
            ImagePipelineFactory.getInstance().platformBitmapFactory,
            bitmapFrameRenderer,
            Bitmap.Config.ARGB_8888,
            DefaultSerialExecutorService(Executors.newCachedThreadPool())
        )
        val bitmapAnimationBackend = BitmapAnimationBackend(
            ImagePipelineFactory.getInstance().platformBitmapFactory,
            bitmapFrameCache,
            AnimatedDrawableBackendAnimationInformation(animatedDrawableBackend),
            bitmapFrameRenderer,
            FixedNumberBitmapFramePreparationStrategy(3),
            bitmapFramePreparer
        )
        return AnimationBackendDelegateWithInactivityCheck.createForBackend(
            bitmapAnimationBackend,
            RealtimeSinceBootClock.get(),
            UiThreadImmediateExecutorService.getInstance()
        )
    }
}

look FrescoFrameCache with reuse

val controller: DraweeController = Fresco.newDraweeControllerBuilder()
            .setUri("https://p3-webcast.douyinpic.com/img/webcast/audio_bg_6_animated_3.webp~tplv-obj.image")
            .setCustomDrawableFactory(MultiDrawableFactory())
            .setAutoPlayAnimations(true)
            .build()
binding.myImageView.controller = controller

Solution

what lead to OOM is function clone in class DefaultCloseableReference: mStacktrace != null ? new Throwable(mStacktrace), so many Throwable would be created. use mStacktrace != null ? mStacktrace instead of it

Additional Information

wying111 commented 2 years ago

modify private var animatable: Animatable? = null to private var animatable: WeakReference? = null

stale[bot] commented 2 years ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as "bug" or "enhancement" and I will leave it open. Thank you for your contributions.