kbroulik / lottie-qml

QML Item for rendering Lottie Web animations in a QtQuick Canvas
71 stars 12 forks source link

Memory issues if animation is loaded and destroyed several times. #1

Open ThomasVogelpohl opened 5 years ago

ThomasVogelpohl commented 5 years ago

Hi kbroulik,

at first thank you for your Lottie QML wrapper, it really works quite well.

Unfortunately, I do have issues with increasing memory demand. If I monitor the memory demand with the QML Profiler, the demand for memory is increasing each time I load a Animation JSON file.

This is a screenshot from the QML Profiler: https://github.com/ThomasVogelpohl/lottie-qml/blob/master/screenshots/Screenshot%202019-02-06%20at%2021.17.16.png

I have tried calling the destroy() functions for the JavaScript lib, but it does not seem to make any difference.

I have forked your Repo and added a few files to be able to easily demonstrate the problem:

  1. Clone: https://github.com/ThomasVogelpohl/lottie-qml/commits/master
  2. Load the OwnLottieCompiler.pro in QT Creator.
  3. Compile and start the QML Profiler

The code will load and unload a Lottie Animation 10 times. You see that the memory bars are steadily increasing.

So you have any suggestion on what to try to release the memory ?

Thanks, Thomas

Evil-Spirit commented 5 years ago

I have decreased some of leaks by adding to LottieAnimation.qml the following lines:

        Component.onDestruction: {
            if (animationItem) {
                animationItem.destroy();
                animationItem = null;
            }
     } 
kbroulik commented 5 years ago

Good suggestion! There's a destroyAnimation() method that does that, perhaps you can just wire that up as (unless it's already destroyed at that point)

Component.onDestruction: d.destroyAnimation()

Feel free to submit a pull request

Evil-Spirit commented 5 years ago

Calling "destroyAnimation" causes error for my code because of "canvas.clear" call.

ThomasVogelpohl commented 5 years ago

Hello all, thanks for your help on this issue.

I have noticed the missing call to the Lottie.destroy function as well. Unfortunately, it is not fixing the leak completely, just improving it.

I think I found another leak source ..... pun intended ;-)

In lottie_shim.js we are loading the lottie.js lib with Qt.include(): var lottieJs = Qt.include("../3rdparty/lottie.min.js");

Qt.include does copy the whole javascript file into the namespace of the including object. (Written here at the bottom: https://doc.qt.io/qt-5/qtqml-javascript-imports.html) But in the case of lottie-qml the lottie lib is not loaded directly into lottie_shim.js, but into the function initialise(). And there it might not get released.

I have tried to reproduce the issue again in the repo: https://github.com/ThomasVogelpohl/lottie-qml/commits/master

I have added a new Component in main.qml which just displays a blue rectangle (it does not load Lottie) Now you need to instruct the Loader which Component to load: loader.sourceComponent = animationArea // animationAreaTest For the following test, set animationAreaTest.

The situation of loading the lib with Qt.include() has been duplicated in script.js: Now you need to instruct the code where to load the javascript file factorial.js with the following line: var lottieJs = Qt.include("factorial.js")

a) Load factorial.js in the function showCalculations(value) b) Load factorial.js in root of script.js

In case of situation a) the code is leaking memory (check with QmlProfiler) in case of b), no leaks occur. But the code works.

I have tried to apply version b) to lottie-qml, but without success. I do not really understand the window and document and therefore wanted to ask if anybody of you understands how to reduce that leak.

Thanks for your help and best regards, Thomas

Evil-Spirit commented 5 years ago

@ThomasVogelpohl I also have refactor this thing but not because of leak but because of annoying reparsing js code when load/unload different qmls with LottieAnimation. It leads to performace problems.

lottie.min.zip lottie_shim.zip

kbroulik commented 5 years ago

I don't have much time to investigate or look into any of this, feel free to submit a merge request and I'll review there, all of your explanations and code snippets do look sane.

Evil-Spirit commented 5 years ago

@kbroulik no problem. I also have no time to make a request because my changes breaks lottie.min.js so you can't update it easily. Writing here just to help if someone have the same issues.

Also, about leaks. I figured out what with the last qt framework version I almost have no leaks for my files attched above (not tested a lot, but much better than previous versions).

kbroulik commented 5 years ago

Btw, eventually this module would be obsolete as Qt has an implementation on their own. It's still software-rendered but using QPainter and C++ code rather than a Canvas with JavaScript logic.

I haven't tried it myself yet: https://code.qt.io/cgit/qt/qtlottie.git/

ThomasVogelpohl commented 5 years ago

@kbroulik Thanks for the info ! qtlottie is planned as a Technology Preview for Qt 5.13: https://wiki.qt.io/New_Features_in_Qt_5.13 and the first Beta is planned for the 26.02.

I have tested Lottie with the qtlottie Repo and some animations are working and some are not. It is a mixed bag, as expected for an early Beta release. But I do consider it a good start.

Evil-Spirit commented 5 years ago

Thanks, I also tested and this is not quite working for my animations. But hope this will be fixed soon!

lizsde commented 3 years ago

@kbroulik I tried the new Qt Lottie Animation and it still doesn't work for my animations. So give this a try. One thing I notice is that the performance went really bad after I update qt from 5.12 to 5.15. Screenshot attached. I limited the exe to ran on only CPU2 and the core has been busy 100% with qt 5.15(left img). Right side CPU performance img is with qt 5.12. I know it's been two years after this thread but still want to check if anyone has any idea why the performance had gone so bad with new qt version image