fix($rootScope): fix potential memory leak when removing scope listeners
When removing listeners they are removed from the array but the array size is not changed until the event is fired again. If the event is never fired but listeners are added/removed then the array will continue growing. By changing the listener removal to `delete` the array entry instead of setting it to `null` browsers can potentially deallocate the memory for the entry. Fixes #16135 Closes #16161
This commit is contained in:
committed by
Martin Staffa
parent
e5fb92978f
commit
97d0224ae6
+4
-1
@@ -1273,7 +1273,10 @@ function $RootScopeProvider() {
|
||||
return function() {
|
||||
var indexOfListener = namedListeners.indexOf(listener);
|
||||
if (indexOfListener !== -1) {
|
||||
namedListeners[indexOfListener] = null;
|
||||
// Use delete in the hope of the browser deallocating the memory for the array entry,
|
||||
// while not shifting the array indexes of other listeners.
|
||||
// See issue https://github.com/angular/angular.js/issues/16135
|
||||
delete namedListeners[indexOfListener];
|
||||
decrementListenerCount(self, 1, name);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2438,6 +2438,21 @@ describe('Scope', function() {
|
||||
}));
|
||||
|
||||
|
||||
// See issue https://github.com/angular/angular.js/issues/16135
|
||||
it('should deallocate the listener array entry', inject(function($rootScope) {
|
||||
var remove1 = $rootScope.$on('abc', noop);
|
||||
$rootScope.$on('abc', noop);
|
||||
|
||||
expect($rootScope.$$listeners['abc'].length).toBe(2);
|
||||
expect(0 in $rootScope.$$listeners['abc']).toBe(true);
|
||||
|
||||
remove1();
|
||||
|
||||
expect($rootScope.$$listeners['abc'].length).toBe(2);
|
||||
expect(0 in $rootScope.$$listeners['abc']).toBe(false);
|
||||
}));
|
||||
|
||||
|
||||
it('should call next listener after removing the current listener via its own handler', inject(function($rootScope) {
|
||||
var listener1 = jasmine.createSpy('listener1').and.callFake(function() { remove1(); });
|
||||
var remove1 = $rootScope.$on('abc', listener1);
|
||||
|
||||
Reference in New Issue
Block a user