This is a somewhat complex memory leak made even more complex by my only vague familiarity with AngularJS. I will do my best to explain what is going on!
Steps to Reproduce
Visit the Dashboard of a Piwik installation.
Open up the devtools console, and inspect the length of the following property:
Note 2: You have two instances of jQuery on the page, which both use different numbers in their properties. Typically, the larger of the two has the $scope property.
Click on the "Dashboard" link in the menu to refresh the dashboard.
Re-inspect the property, noting how it has doubled in length.
Cause
compileAngularComponents is to blame; specifically, this line:
The call to $compile causes AngularJS to register the $destroy handler on the element's scope. However, the scope is never destroyed -- it is re-used across dashboard visits.
Solution
Is it possible to destroy and re-create the scope when you redraw the dashboard? If not, then perhaps you can remove all of these listeners as a hackfix when the dashboard is redrawn?
Alternatively, are you supposed to re-compile these widgets when you revisit the dashboard? I honestly don't know. :-)
Impact
To measure the impact of this leak on Piwik's heap size, I hackfixed the leak by simply removing the line in Angular JS that adds the listener. Here is the result:
The text was updated successfully, but these errors were encountered:
This is a somewhat complex memory leak made even more complex by my only vague familiarity with AngularJS. I will do my best to explain what is going on!
Steps to Reproduce
window.$widgetContent[0].jQuery[long number].$scope.$$listeners.$destroy
$scope
property.Cause
compileAngularComponents
is to blame; specifically, this line:https://github.com/piwik/piwik/blob/9c7d7ff1c842132bc8f3f0ff8c296eb7d3959c30/plugins/Morpheus/javascripts/piwikHelper.js#L123
The call to
$compile
causes AngularJS to register the$destroy
handler on the element's scope. However, the scope is never destroyed -- it is re-used across dashboard visits.Solution
Is it possible to destroy and re-create the scope when you redraw the dashboard? If not, then perhaps you can remove all of these listeners as a hackfix when the dashboard is redrawn?
Alternatively, are you supposed to re-compile these widgets when you revisit the dashboard? I honestly don't know. :-)
Impact
To measure the impact of this leak on Piwik's heap size, I hackfixed the leak by simply removing the line in Angular JS that adds the listener. Here is the result:
The text was updated successfully, but these errors were encountered: