Small Memory Leak in $rootScope.$on #16135
Description
I'm submitting a ...
- bug report
- feature request
- other (Please do not submit support requests here (see above))
Current behavior:
Registering a new handler with $rootScope.$on
push
es the handler to the end of a list. Removing the handler only null
s out the array index that contains the handler. The code never resizes the array to remove the null
entries, leading to an array that grows without bounds.
Given:
- An event
'e'
such that there is always 1 registered listener on the event (preventing the handler list from being removed).- Note that this is easily achievable even if all handlers are regularly removed. All it takes is another call to
$on('e', handler)
to run before all handlers are de-registered.
- Note that this is easily achievable even if all handlers are regularly removed. All it takes is another call to
- An application that regularly calls
$rootScope.$on('e'
, handler)` and responsibly de-registers the handler over the course of a session
...then the handler list for 'e'
will grow by 1 element every time $rootScope.$on('e', handler)
is called. The end result is an array that looks like this: [null, null, null, ... handler, handler]
.
I'm observing this happen in an app with the $translateChangeSuccess event. The array grows to about 40 null
entries over 8 navigations to different views/pages.
The leak is small, but avoidable.
Expected / new behavior:
The handler list does not grow unboundedly over the course of a session. Handler positions are either re-used (as in a free list-based memory allocator), or handlers are registered in an object where handler positions are delete
-ed once they are de-registered.
Minimal reproduction of the problem with instructions:
See above description.
Angular version: Observed in 1.4.1, but code still present in 1.6.
Browser:
All
Anything else:
See above for suggestions on how to fix.
Note that I am not heavily experienced with AngularJS, but I am heavily experienced in JavaScript. Hence, I am not able to provide you with a succinct reproduction of the issue, but the description and a quick glance of the code should confirm the problem.