[ARM/ARM64] Android 5.0 Lollipop bootanimation memory leak fix

Search This thread

arter97

Recognized Developer
Oct 14, 2012
3,890
34,674
26
Seoul
/* Info */
There's a known issue on Android 5.0 Lollipop.

The bootanimation binary(/system/bin/bootanimation - Responsible for initial boot animations during bootup) causes a serious memory leak, too exhaustive that core system services or other processes can be killed during boot,
or on the worst case, endless boot loop due to core system services unable to initialize.

/* Why? */
My theory is, the current bootanimation implementation does not releases the resources held to play previous frames.

Testing this on a Galaxy S4 with a 1080p bootanimation.zip file resulted in 200MB of RAM usage in 3 seconds, and the kernel starts to kill processes in 10 seconds.
With a Nexus 7, luckily, it did pass on the bootanimation and showed up the lock-screen. However, some services got killed during boot and resulted in an overall unstable system.


I've been able to reproduce this bug on majority of devices including Galaxy Note 3, Galaxy S4, Nexus 7, Nexus 5, Nexus 4 and much more with CyanogenMod 12, Google's pure/stock AOSP and LG's Lollipop firmware.
I'm almost certain that other Android 5.0 Lollipop ROMs may have the same problem(except for Samsung's Touchwiz - Touchwiz uses qmg format and I was unable to reproduce this bug on Touchwiz).

You maybe asking yourself -
"But CM12 has this issue solved?"
Short answer is no, they've just put a band-aid on it - reducing framerate and clearing up caches more aggressively to "workaround", and this is not a permanent solution.
"What about other manufacturer's ROM?"
On my test, Samsung's Touchwiz was the only ROM that has this issue solved(probably thanks to the their proprietary qmg format). Other manufacturers - LG, hTC and more - may also suffer from the same bug.
"Can I expect this fix to be integrated with CyanogenMod 12 nightlies?"
Maybe. I've sent this fix to CyanogenMod Gerrit code review. If they approve it, it'll be integrated into future nightly builds.

/* Solution? */
Before I could have come up with a permanent solution, I suggested users to remove /system/bin/bootanimation from their devices for now, as this is a very serious issue.
Now, I've got a working, permanent fix.

V2 - Much cleaner code & misc fixes with some bootanimation.zip files

The attached "bootanimation.zip" contains 3 binaries.
cm12/bootanimation is for CyanogenMod 12(or its fork) users
aosp/<CPU architecture>/bootanimation is for pure/stock AOSP(or its fork) users & manufacturer's ROM users & Nexus users with stock ROM installed.
<You must install the right bootanimation binary for your device's CPU architecture; users will most likely install 32bit unless they use Nexus 9 or LG G flex 2>


Download the "bootanimation.zip", extract the right "bootanimation" binary and put it under /system/bin - replacing the old one.
The correct owner is root:root,
the correct permission is 755(rwxr-xr-x).


If those binaries do not work for you, I'm afraid your ROM developer/builder have to integrate the fix into the source code, or not use the bootanimation at all :(

/* Some more technical information */
If you're a ROM developer, who wants to integrate this fix, please read below and cherry-pick the correct fix.
Android Issue tracker - https://code.google.com/p/android/issues/detail?id=140061
CyanogenMod Gerrit code review - http://review.cyanogenmod.org/88968
CyanogenMod Gerrit GitHub - https://github.com/CyanogenMod/andr...mmit/de11ae6610f3c96b07b8e2e1d0dc1531c21ac82f
Android Gerrit code review - https://android-review.googlesource.com/132681
 

Attachments

  • bootanimation.zip
    101.2 KB · Views: 17,538
  • bootanimation_v2.zip
    101.2 KB · Views: 27,638
Last edited:

skyguy126

Senior Member
Sep 17, 2014
454
110
github.com
/* Info */
There's a known issue on Android 5.0 Lollipop.

The bootanimation binary(/system/bin/bootanimation - Responsible for initial boot animations during bootup) causes a serious memory leak, too exhaustive that core system services or other processes can be killed during boot,
or on the worst case, endless boot loop due to core system services unable to initialize.

/* Why? */
My theory is, the current bootanimation implementation does not releases the resources held to play previous frames.

Testing this on a Galaxy S4 with a 1080p bootanimation.zip file resulted in 200MB of RAM usage in 3 seconds, and the kernel starts to kill processes in 10 seconds.
With a Nexus 7, luckily, it did pass on the bootanimation and showed up the lock-screen. However, some services got killed during boot and resulted in an overall unstable system.


I've been able to reproduce this bug on majority of devices including Galaxy Note 3, Galaxy S4, Nexus 7, Nexus 5, Nexus 4 and much more with CyanogenMod 12, Google's pure/stock AOSP and LG's Lollipop firmware.
I'm almost certain that other Android 5.0 Lollipop ROMs may have the same problem(except for Samsung's Touchwiz - Touchwiz uses qmg format and I was unable to reproduce this bug on Touchwiz).

You maybe asking yourself -
"But CM12 has this issue solved?"
Short answer is no, they've just put a band-aid on it - reducing framerate and clearing up caches more aggressively to "workaround", and this is not a permanent solution.
"What about other manufacturer's ROM?"
On my test, Samsung's Touchwiz was the only ROM that has this issue solved(probably thanks to the their proprietary qmg format). Other manufacturers - LG, hTC and more - may also suffer from the same bug.
"Can I expect this fix to be integrated with CyanogenMod 12 nightlies?"
Maybe. I've sent this fix to CyanogenMod Gerrit code review. If they approve it, it'll be integrated into future nightly builds.

/* Solution? */
Before I could have come up with a permanent solution, I suggested users to remove /system/bin/bootanimation from their devices for now, as this is a very serious issue.
Now, I've got a working, permanent fix.

The attached "bootanimation.zip" contains 3 binaries.
cm12/bootanimation is for CyanogenMod 12(or its fork) users
aosp/<CPU architecture>/bootanimation is for pure/stock AOSP(or its fork) users & manufacturer's ROM users & Nexus users with stock ROM installed.
<You must install the right bootanimation binary for your device's CPU architecture; users will most likely install 32bit unless they use Nexus 9 or LG G flex 2>


Download the "bootanimation.zip", extract the right "bootanimation" binary and put it under /system/bin - replacing the old one.
The correct owner is root:root,
the correct permission is 755(rwxr-xr-x).


If those binaries do not work for you, I'm afraid your ROM developer/builder have to integrate the fix into the source code, or not use the bootanimation at all :(

/* Some more technical information */
If you're a ROM developer, who wants to integrate this fix, please read below and cherry-pick the correct fix.
Android Issue tracker - https://code.google.com/p/android/issues/detail?id=140061
CyanogenMod Gerrit code review - http://review.cyanogenmod.org/88918
CyanogenMod Gerrit GitHub - https://github.com/CyanogenMod/andr...mmit/6b0cabc4d0a131800bd7ff75f0653e4c0cd7d3a4
Android Gerrit code review - https://android-review.googlesource.com/132562

Explains why my new CM12 flashes end up in a bootloop.
 

zamzameir

Senior Member
Sep 11, 2013
347
418
Kuala Lumpur
how about using the lollipop bootanim on the older android version like kk. do I need to do the same fix as well ? show me the light please :)
 

NuShrike

Senior Recognized Developer
Sep 18, 2007
1,128
69
If this is because Google is using its AnimationDrawable for the bootanimation, then it's part of the half-ass SDK Google is still putting out.

AnimationDrawable loads ALL frames and never releases previous-frames during playback until the entire drawable is unloaded.

You would think after GIF, MPEG, MNG or APNG (animated PNG), SVG, etc, Google wouldn't go back to pre-school raw-frame animations.

edit: looking at the actual patch, that animation GL animation code from Google is pretty bad. Generating a new texture id per frame is stupid, and using only one texture otherwise, is just as bad. It should be 2, or 3 texture ids reused continuously in a ring-buffer, and that's it.

So, removing the GL code at lines 786-791 is bad because it's generating a texture for all the frames that are coming up. Dropping that means it drops all the frames that was going to get used.
Deleting lines 837-841 causes a texture memory id leak, though no texture-memory leak due to lines 786-791 being deleted. I'd agree with comment https://code.google.com/p/android/issues/detail?id=140061#c6

The way "Animation" on line 608 is used, it looks very much like an AnimationDrawable. So this whole thing is typical of Google not having coders that can do proper animation code.
 
Last edited:

domenukk

Senior Member
Jan 11, 2010
823
31
/* Info */
/* Why? */
My theory is, the current bootanimation implementation does not releases the resources held to play previous frames.
As long as the loaded frames get reused, this makes a lot of sense, doesn't it?
It's faster to display the frame from memory than to load it again.
As long as the boot animation doesn't get overly large, which it usually doesn't do, this should not be an issue.
Or do I miss something here?
 

arter97

Recognized Developer
Oct 14, 2012
3,890
34,674
26
Seoul

javelinanddart

Recognized Dev / Inactive Recognized Contributor
Mar 28, 2014
1,485
1,832
Midwest
/* Info */
There's a known issue on Android 5.0 Lollipop.

The bootanimation binary(/system/bin/bootanimation - Responsible for initial boot animations during bootup) causes a serious memory leak, too exhaustive that core system services or other processes can be killed during boot,
or on the worst case, endless boot loop due to core system services unable to initialize.
.....
/* Some more technical information */
If you're a ROM developer, who wants to integrate this fix, please read below and cherry-pick the correct fix.
Android Issue tracker - https://code.google.com/p/android/issues/detail?id=140061
CyanogenMod Gerrit code review - http://review.cyanogenmod.org/88968
CyanogenMod Gerrit GitHub - https://github.com/CyanogenMod/andr...mmit/de11ae6610f3c96b07b8e2e1d0dc1531c21ac82f
Android Gerrit code review - https://android-review.googlesource.com/132681

Thanks man! If I get around to building ROMs I'll include this patch for sure!
 

arter97

Recognized Developer
Oct 14, 2012
3,890
34,674
26
Seoul
If this is because Google is using its AnimationDrawable for the bootanimation, then it's part of the half-ass SDK Google is still putting out.

AnimationDrawable loads ALL frames and never releases previous-frames during playback until the entire drawable is unloaded.

You would think after GIF, MPEG, MNG or APNG (animated PNG), SVG, etc, Google wouldn't go back to pre-school raw-frame animations.

edit: looking at the actual patch, that animation GL animation code from Google is pretty bad. Generating a new texture id per frame is stupid, and using only one texture otherwise, is just as bad. It should be 2, or 3 texture ids reused continuously in a ring-buffer, and that's it.

So, removing the GL code at lines 786-791 is bad because it's generating a texture for all the frames that are coming up. Dropping that means it drops all the frames that was going to get used.
Deleting lines 837-841 causes a texture memory id leak, though no texture-memory leak due to lines 786-791 being deleted.

I'm not a OpenGL expert, I've just messed around the code to find out how to fix it "apparently".

You may wanna go read comments here https://code.google.com/p/android/issues/detail?id=140061 (especially #7 and #8).

Can you come up with a better patch?
 
  • Like
Reactions: XblackdemonX

coolhz

Senior Member
Nov 3, 2013
131
61
There is no problem with LG firmware

@arter97 I own a LG G3 updated to latest Lollipop firmware from LG(i.e. official firmware) , and I assure you that this bug has been fixed by LG and everything is working as it should , no bootloops or anything in the normal usage is buggy.
 

Top Liked Posts

  • There are no posts matching your filters.
  • 394
    /* Info */
    There's a known issue on Android 5.0 Lollipop.

    The bootanimation binary(/system/bin/bootanimation - Responsible for initial boot animations during bootup) causes a serious memory leak, too exhaustive that core system services or other processes can be killed during boot,
    or on the worst case, endless boot loop due to core system services unable to initialize.

    /* Why? */
    My theory is, the current bootanimation implementation does not releases the resources held to play previous frames.

    Testing this on a Galaxy S4 with a 1080p bootanimation.zip file resulted in 200MB of RAM usage in 3 seconds, and the kernel starts to kill processes in 10 seconds.
    With a Nexus 7, luckily, it did pass on the bootanimation and showed up the lock-screen. However, some services got killed during boot and resulted in an overall unstable system.


    I've been able to reproduce this bug on majority of devices including Galaxy Note 3, Galaxy S4, Nexus 7, Nexus 5, Nexus 4 and much more with CyanogenMod 12, Google's pure/stock AOSP and LG's Lollipop firmware.
    I'm almost certain that other Android 5.0 Lollipop ROMs may have the same problem(except for Samsung's Touchwiz - Touchwiz uses qmg format and I was unable to reproduce this bug on Touchwiz).

    You maybe asking yourself -
    "But CM12 has this issue solved?"
    Short answer is no, they've just put a band-aid on it - reducing framerate and clearing up caches more aggressively to "workaround", and this is not a permanent solution.
    "What about other manufacturer's ROM?"
    On my test, Samsung's Touchwiz was the only ROM that has this issue solved(probably thanks to the their proprietary qmg format). Other manufacturers - LG, hTC and more - may also suffer from the same bug.
    "Can I expect this fix to be integrated with CyanogenMod 12 nightlies?"
    Maybe. I've sent this fix to CyanogenMod Gerrit code review. If they approve it, it'll be integrated into future nightly builds.

    /* Solution? */
    Before I could have come up with a permanent solution, I suggested users to remove /system/bin/bootanimation from their devices for now, as this is a very serious issue.
    Now, I've got a working, permanent fix.

    V2 - Much cleaner code & misc fixes with some bootanimation.zip files

    The attached "bootanimation.zip" contains 3 binaries.
    cm12/bootanimation is for CyanogenMod 12(or its fork) users
    aosp/<CPU architecture>/bootanimation is for pure/stock AOSP(or its fork) users & manufacturer's ROM users & Nexus users with stock ROM installed.
    <You must install the right bootanimation binary for your device's CPU architecture; users will most likely install 32bit unless they use Nexus 9 or LG G flex 2>


    Download the "bootanimation.zip", extract the right "bootanimation" binary and put it under /system/bin - replacing the old one.
    The correct owner is root:root,
    the correct permission is 755(rwxr-xr-x).


    If those binaries do not work for you, I'm afraid your ROM developer/builder have to integrate the fix into the source code, or not use the bootanimation at all :(

    /* Some more technical information */
    If you're a ROM developer, who wants to integrate this fix, please read below and cherry-pick the correct fix.
    Android Issue tracker - https://code.google.com/p/android/issues/detail?id=140061
    CyanogenMod Gerrit code review - http://review.cyanogenmod.org/88968
    CyanogenMod Gerrit GitHub - https://github.com/CyanogenMod/andr...mmit/de11ae6610f3c96b07b8e2e1d0dc1531c21ac82f
    Android Gerrit code review - https://android-review.googlesource.com/132681
    47
    Reserved

    Reserved
    17
    I'm not a OpenGL expert, I've just messed around the code to find out how to fix it "apparently".

    You may wanna go read comments here https://code.google.com/p/android/issues/detail?id=140061 (especially #7 and #8).

    Can you come up with a better patch?
    Don't take me wrong. I don't disagree this attempts the fix the Google memory-resource foobar. However, the fix could be better.

    I suggest instead:
    original line 778 add:
    Code:
        const size_t FRAME_CACHE = 2;
        GLuint frame_tid[FRAME_CACHE];
        size_t frame_tid_ref = 0;
        glGenTexture(FRAME_CACHE, frame_tid);  // swap between FRAME_CACHE pre-allocated textures
        for(ssize_t j = FRAME_CACHE - 1; j >= 0; j--) {  // configure textures
            glBindTexture(GL_TEXTURE_2D, frame_tid[j]);
            glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);		
        }

    original line 780 to 795 change to:
    Code:
        nsecs_t lastFrame = systemTime();
        if (r > 0 && j == 0) {  // "pre"-load texture only once here before multi-frame animation
            const Animation::Frame& frame(part.frames[j]);
            glBindTexture(GL_TEXTURE_2D, frame_tid_ref++);
            frame_tid_ref %= FRAME_CACHE;
            initTexture( initTexture( frame.map->getDataPtr(),
                                                      frame.map->getDataLength());
        }

    original line 812 add:
    Code:
        if ( r > 0 && (j > 0 && (j + 1 < fcount)) ) {  // pre-load texture before sleep to use up slack time
            const Animation::Frame& frame(part.frames[j+1]);
            glBindTexture(GL_TEXTURE_2D, frame_tid_ref++);
            frame_tid_ref %= FRAME_CACHE;
            initTexture( initTexture( frame.map->getDataPtr(),
                                                      frame.map->getDataLength());
        }

    original line 838-843 change to:
    Code:
        glDeleteTextures(2, frame_tid);

    Debug before use.

    Permission is given to anybody to use this code EXCEPT for Google. I'm usually paid for this work, and Google doesn't deserve it.

    There's an even better version that's multi-threaded, but that's premium :cool:
    13
    If this is because Google is using its AnimationDrawable for the bootanimation, then it's part of the half-ass SDK Google is still putting out.

    AnimationDrawable loads ALL frames and never releases previous-frames during playback until the entire drawable is unloaded.

    You would think after GIF, MPEG, MNG or APNG (animated PNG), SVG, etc, Google wouldn't go back to pre-school raw-frame animations.

    edit: looking at the actual patch, that animation GL animation code from Google is pretty bad. Generating a new texture id per frame is stupid, and using only one texture otherwise, is just as bad. It should be 2, or 3 texture ids reused continuously in a ring-buffer, and that's it.

    So, removing the GL code at lines 786-791 is bad because it's generating a texture for all the frames that are coming up. Dropping that means it drops all the frames that was going to get used.
    Deleting lines 837-841 causes a texture memory id leak, though no texture-memory leak due to lines 786-791 being deleted. I'd agree with comment https://code.google.com/p/android/issues/detail?id=140061#c6

    The way "Animation" on line 608 is used, it looks very much like an AnimationDrawable. So this whole thing is typical of Google not having coders that can do proper animation code.
    9
    FYI, Google have not patched this bootanimation memory leakages on Android 5.1.