-
Notifications
You must be signed in to change notification settings - Fork 27.5k
Significant memory leak, possibly caused by ng-repeat #6429
Comments
This strangely reminds me of #4864 which, as far as I remember, was declared as a bug in dev tools: https://code.google.com/p/chromium/issues/detail?id=304689 See more details here: #4864 (comment) |
I don't think it's just a Chrome bug, I'm tearing my hair out with the same issue that I was able to reproduce in IE11. I've just spent a day and a half debugging the exact same issue- switching between routes has been causing steady creeps in memory usage, up to the point where it crashes chrome, and the biggest pushers of memory have been pages with nested ng-repeat directives. I've reproduced the issue in IE11 as well, and can reproduce in the heap snapshots as well. I can't demo code yet- too much business specific code- but I'm at the point where I may spend a few hours coming up with a safe to share example. I will say the biggest standout from what I've been able to see has been tons and tons of detached DOM nodes / trees. If someone doesn't beat me to it, I'll edit with a |
On second thought, maybe I'm seeing something different- in c0bra's http://embed.plnkr.co/v9HVH4/ example, hitting Collect Garbage on the timeline was bringing DOM Node count down to 6329 each time. |
@dzdrazil if it (reliably) crashes Chrome, have you been able to crash it without the Developer tools open or recording the memory usage? |
@dzdrazil just fyi I tried that on my plunker after I saw your comments. It leaks whether or not the developer tools are open, based on the Chrome task manager. |
@Narretz, in my paritcular case, I was able to show in multiple browsers that memory was leaking- it had something to do with objects on a $scope that had arrays, which were then accessed by templates. Detatched DOM trees galore! I was able to resolve it by adding $scope.$on('$destroy'... everywhere, but that's an issue unrelated to this ticket, and I'll file it once I have a minimalist code sample to prove it. @c0bra, I'm convinced it's not a memory leak so much as it is the loop is creating garbage so quckly and consistently that GC won't kick in in time to save the session. Try this- click on single swap once a second. In my experience, memory use grew to and capped out at 125mb (looking at js memory in the chrome task manager). Even with clicking it quickly, then pausing a bit, then clicking some more, then pausing a bit, the most I could get it up to was 200mb before (slowing down the clicking and extending the pauses) it eventually settled back at the 60-70mb baseline. |
I'm seeing the same behavior. Can't prove it yet but working on a sample. Looks like things are being held there by a variable named "clone". But I could just be mis-reading the dev tools output. |
I'm seeing the same behavior as well. As soon as I removed the ng-repeat, the leaks were gone. The plnkr very clearly shows this. Any chance on getting a fix for this? |
I'm looking into this. |
I can't reproduce the leak. Timeline shows the usual stuff - we generate garbage as the routes are swapping back and forth, GC kicks in and does minor collections here and there. Even if I keep on repeating the sequence I don't see any major memory retention and most importantly if I force garbage collection (between 1.6m and 1.7m), the heap is cleaned up and memory usage drops to almost nothing. Taking heap snapshots didn't show anything either. The snapshots take about 16MB. It's important to know that while taking a snapshot automatically forces full GC, simply recording a timeline does not. That's why I forced GC in my recording. My take is that you do have a memory leak, but it's not due to ngRepeat. ngRepeat only makes it easy to turn a small memory leak somewhere else, into a much bigger and easier to spot issue. (btw I also tried to run your app on FF and watched the memory consumption of the FF process and didn't see anything that would tell me that there is a leak in this plunk). Lastly, when profiling the plunk please make sure that you run in its raw form - that is without any plnkr code. By default plnkr runs the code in an iframe and if you profile such app you'll see stuff coming from both the plunker code and your app. I used this url to do all of my investigation: http://run.plnkr.co/plunks/v9HVH4/ (btw I used Chrome 33.0.1750.152) |
Can you please update this issue with a plunk that leaks (using the process I described above)? |
@IgorMinar that original plunk did leak using your process. In my # 2 note you can see that the leak was occurring with the plunk files downloaded to my local machine and ran straight in the browser from a local file/simple http server. I never bothered to test in edit mode with the iframe as it was too noisy. That being said, when I check the plunk now it's behaving differently. Memory use stabilizes at about 75MB and does not increase no matter how many times I run the "Swap Loop" process. I wonder if Chrome has a fix that came out in the past couple weeks. I'm on 33.0.1750.146 now.
That was my initial guess, but when I was unable to locate the source in my own app and found what appeared to be the same leak behavior in raw ngRepeat, I posted this issue. Since it seems like the leak cannot be reproduced in latest Chrome, I'll double-check my app and see if the leak is gone there as well. |
sounds good! I know that v8 guys are working and several refactorings to address this issue. It's possible that one of them has been rolled out already and that made the leak for this particular case go away. Please open a new issue when you have the reduction. |
I've spent the last couple days tracking down a memory leak in a custom directive and decided to try reproducing it with just pure ng-repeat. You can see a demo here (wait the for XHR to load):
http://embed.plnkr.co/v9HVH4/
The plunker swaps between identical routes every 1/4 second, a total of 20 times. You can see the memory in the developer tools timeline grow by about 6MB per route change (from 14MB to ~140MB for me).
Some notes:
The text was updated successfully, but these errors were encountered: