diff options
author | John Vilk <jvilk@cs.umass.edu> | 2017-03-26 00:12:47 +0300 |
---|---|---|
committer | Stefan Giehl <stefan@piwik.org> | 2017-03-26 00:12:47 +0300 |
commit | 4138e951366b796bb52b7750443aa207595038f4 (patch) | |
tree | c26254d28f03fa020749acdaa86d4c010602aedc /plugins/CoreHome/javascripts/uiControl.js | |
parent | 61c3e8dcfc30fe7728f57493eec2f40600b255f4 (diff) |
Fix UIControl memory leak (#11362)
Previously, every `UIControl` ever created would be stored in `UIControl._controls`. During cleanup, every `UIControl` would be checked to see if it is still active in the DOM, but would never be removed from the array.
Now, cleanup only retains a reference to active `UIControl` instances. This change also decouples `UIControl` IDs from the length of the array.
Diffstat (limited to 'plugins/CoreHome/javascripts/uiControl.js')
-rw-r--r-- | plugins/CoreHome/javascripts/uiControl.js | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/plugins/CoreHome/javascripts/uiControl.js b/plugins/CoreHome/javascripts/uiControl.js index cd2d985ea4..29b8f08711 100644 --- a/plugins/CoreHome/javascripts/uiControl.js +++ b/plugins/CoreHome/javascripts/uiControl.js @@ -22,7 +22,7 @@ throw new Error("no element passed to UIControl constructor"); } - this._controlId = UIControl._controls.length; + this._controlId = UIControl._nextControlId++; UIControl._controls.push(this); var $element = this.$element = $(element); @@ -45,6 +45,11 @@ UIControl._controls = []; /** + * Specifies the next unique control ID to use. + */ + UIControl._nextControlId = 0; + + /** * Utility method that will clean up all piwik UI controls whose elements are not attached * to the DOM. * @@ -53,6 +58,9 @@ */ UIControl.cleanupUnusedControls = function () { var controls = UIControl._controls; + // reset _controls; we will repopulate it with only active + // controls in the loop below. + var activeControls = UIControl._controls = []; for (var i = 0; i != controls.length; ++i) { var control = controls[i]; @@ -67,6 +75,9 @@ throw new Error("Error: " + control.constructor.name + "'s destroy method does not call " + "UIControl.destroy. You may have a memory leak."); } + } else { + // Control is still active / used. + activeControls.push(control); } } }; |