Leaking $scope when method on scope references $scope itself #5527
Description
When we have a view / child scope which is added and removed to page and in that view we have a controller that adds methods to it's scope which reference $scope in body of method like
$scope.flipFlag = function(){ $scope.flag = !$scope.flag }
When view is destroyed the scope and all watchers on scope and anything they reference is leaked.
If instead you write method like
$scope.flipFlag = function(){ this.flag = !this.flag }
Then there seems to be no leak.
Might be related to #4026
Reproduction can be seen at http://plnkr.co/edit/JZbtZ13Ml1aDjNJug1gu?p=preview on top of angular 1.2.5. Originally reproduced on our application on top of angular 1.1.4.
What we do in this reproduction is set and unset ng-include to point to a template with a controller.
In the controller we have scope method that references $scope.
To see the leak, on reproduction page, after accessing it, take a heap dump and there on summary view filter by Child constructor.
You will see that there are two scopes leaking, with ids 004 and 005, where 005 is the scope for the controller injected in the view.html and 004 is it's prototype.
From what I can see 004 isn't released because it's held by 005 (as it's prototype).
And 005 isn't released, well here it's not so clear, from what I can see it's not released because it has a function that has it in it's closure / scope.
Running GC several times in chrome does not remove the leaked scope.
In our application this causes the leak of the entire UI (JS and DOM) every time we switch from one view (state) to another, our app is big enough that after a few transitions we see that tab with our app reach 1GB of memory.
More verbose explanation of the issue at https://groups.google.com/d/msg/angular/5aBiuBZCzus/vJQKk9ebVGkJ