0

I have a problem in my main application, where using the app without refreshing, the memory (and CPU usage) is getting higher.

I managed to reproduce it: https://jsfiddle.net/fmgy778r/

angular.module('TestModule', []).controller('TestController', function ($controller, $scope) {
    $scope.a = [];
    for (var i = 0; i < 10 * 1000 * 1000; i++)
        $scope.a.push("stringstring" + i);
});

Press shift + ESC on Chrome.

Now press "problem", and your memory for that tab will be 1GB+-.

Press "default" and see that the memory is still 1GB.

Press "problem" and see that the memory is going down and then up again.

Press "default" once, and then press "problem" 10 times in a fast click spamy way, and see your memory spiking to 1.5-2GB

I have about 30 modules in my system, and if such thing is happening to all, I see why the memory is just bloating.

Why is this happening?

How can it be fixed?

*I know I should use this and not $scope, but I wanted to reproduce the real code.

9
  • I'm not sure why you want 10000000 items inside an array (and the same amount added per clilck). This seems like a very unusual use case. I would assume that this is not angulars fault since the same happens when you use vanilla Javascript. Commented Apr 28, 2016 at 9:35
  • I agree with @DrColossos why you want to loop 10000000 times. the problem is on that part. javascript is client side, don't let your client have hard time. :D Commented Apr 28, 2016 at 10:00
  • Does this change anything for you: jsfiddle.net/fmgy778r/1 ?? Commented Apr 28, 2016 at 10:04
  • By this you are creating 10000000 $scope variables, which is very large number for angular's change detection model. As per my understanding angular can handle upto 10000 $scope variables properly. And if you just want 1 $scope variable with these many values then you can go with solution providede by @Fidel90. Commented Apr 28, 2016 at 10:14
  • @DrColossos This is really not the point.. there are no 10,000,000 variables in my controllers, lets say, a hundrad per controller sounds modest. The thing is, that after leaving that page, and destroying that scope, the memory is still being used. Commented Apr 28, 2016 at 10:44

1 Answer 1

1

I think I understand now what you want. I tested it with your provided and a newer version (1.4.8 is available in fiddle).

Without modifications, my Chrome (64-bit, Linux, 8GB) uses initial 120MB, after clicking "problem", it goes up to more than 1 GB and stays there.

But if you add

$scope.$on('$destroy', function() {
   $scope.a = [];
});

into your first controller, the memory will go back down. Note that this is not immediate but after the next run of the garbage collector (on my machine, this happened after approx. 5 - 15 sec). After the GC ran, the memory goes back to the initial value. Event with many "problem" clicks, the memory stays constant since "$destroy" event is triggered and the variable is reset and ready for the GC.

Sign up to request clarification or add additional context in comments.

2 Comments

Do you know why angular does not "free/delete/unset" all varaibles on destroy, and I need to do it manually? I have no cases like this^ when there is only one variable occupying most of the memory.
I honestly don't know why this is the case but I assume this is more a JS issue than an angular issue. Maybe angular does destroy its scope vars, but GC takes more time to do its thing and this statement is wrong. Maybe someone with deeper angular experience could answer this. Personally, I always to things like this, even in smaller Controllers, Directives, .... Beside, it is best practice to implement such lifecycle methods that do all the clean up.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.