we have a single page application built with javascript, angular, etc.
noticed that in Chrome (only) the memory usage is rising until the tab crash with the "Aw snap" message.
seems like Chrome is not running the garbage collector when it should.
after some research with old Chrome versions i've found that in version 61 everything works very good and the memory usage is very minimal, but in v62 and onward (including canary v66) the GC is not collecting, resulting in memory usage up to few giga. until it crash.
once i open the devtools the GC is collecting as it should and memory usage is normal again.
any idea what is happening?
Chrome developer here. It's hard to guess what might be going on. Please file a bug at crbug.com/new, include repro instructions, and post the bug number here.
Related
I am developing a voxel engine in Javascript using Threejs, and I've run into some memory usage problems. The intended environment is within an Electron application, which means I can launch the program with flags (--expose-gc) that enable manual garbage collection with gc().
I noticed that when running the gc() function, much less memory was freed compared to when I clicked the "collect garbage" button in the Memory section of Chrome's developer tools. For example, if the program initially used 2000 MB of memory, after gc() it would free up to 300 MB, but after clicking the aforementioned button, it would free up to 600 MB more, making it about half of what it originally was.
After some digging, I also found out about the --gc-global flag. This would've been perfect, since it behaved in the same way as a manual gc did, but it ran multiple times per second, making my program extremely laggy. I tried controlling the gc rate with --gc-interval, but it didn't affect it at all.
I also found this answer that talked about ProfilerAgent.collectGarbage();, but it always threw a reference error. Additionally, the flag it provided (--debug-devtools-frontend) wasn't recognised by Chrome. That, and the fact that I could find very little info on it outside of the answer, lead me to believe that it's an obsolete feature.
I also profiled the memory usage from the developer tools, and surprisingly, it was much lower compared to the value that Task Manager showed me: it seemed to be unaffected by the leaking memory. This has made it nearly impossible to determine where the memory could be leaking from.
I should also make it clear that while Chrome does garbage-collect on its own, it's far too infrequent, and it rarely does a full gc, meaning that memory usage is about twice of what it could be.
In summary, is there a way to trigger a full garbage collection from either Chrome or nodejs/Electron? Obviously, I'm not concerned about cross-browser support, so any advice would be appreciated.
It turns out that self.gc only collects garbage in the thread/worker it was called from. Running the function in all of my workers freed as much memory as the developer tools garbage collector did.
I suspect my one-page javascript app contains a memory leak somewhere. Weak devices running Firefox or Chrome seem to crash eventually if the page is left open. I'm trying to determine whether reloading the page would be expected to free the memory or not.
I understand that memory handling is specific to the browser, so the answer may differ in Chrome or Firefox.
NOTE: I recognize that browsers are mentioned a lot in this question (which would be off topic), but the point of this question is about javascript debugging, which I think is very on topic.
Barring browser/extension bug, browsers free up resources when they are no longer needed; Firefox clears compartments, Chrome kills processes and associated storage.
Firefox does its best but may take some time to clear the memory and may create zombie compartments on occasion:
Compartments are destroyed when they are garbage collected. This happens some time after the last reference to them disappears. This means there can be a delay between a page being closed and its compartments disappearing...
Sometimes, due to bugs in Firefox, the Add-on SDK and/or add-ons, compartments are created that are never destroyed. These are a particular kind of memory leak, and they cause Firefox's memory usage to increase gradually over time, slowing it down and making it more likely to crash.
Chrome uses a process per tab (and really subprocesses for some entities within a tab as well IIRC e.g. plugins, iframes, etc.) to the same effect. Though a quick check against chrome://memory-redirect/ and refreshing a tab looks like the same pid is used. So a refresh is not a completely clean slate.
FWIW Chrome has a "Force Reload" that clears the cache and might be either useful for clearing more memory or a placebo: cmd-shift-r
I'm not really familiar with the internals but I've only seen things not reliably freed up between refreshes when a particular browser is getting too clever and trying to preserve things when you're not changing origins etc. in an effort to boost load performance.
In short, you could be tripping up a browser bug if you're not seeing memory freed as you expect but you'd want to use the various "about:memory" tools to verify that and at that point it would be on you to avoid such behavior and/or report the issue to the browser's dev team.
Otherwise, I think you're best served by addressing your own memory leaks within the page using the various tools available.
A good way to debug the resource usage of JS is to use the Firefox performance monitor within the inspection tool. Firefox Dev Edition has more in-depth tools
Press F12 when on the page and click on the little speedometer icon in the inspect window; this will open the performance monitor. Press the "Start Recording" button and Firefox will begin to benchmark all script timings, CSS activity, user input etc. on the page.
When you feel that it has been running for long enough, stop recording and you will be presented with all the data. At the top will be a chart displaying performance and you can click on any part and examine all the scripts running at that time.
A full tutorial for the performance tools can be found here
My website (www.transferxl.com) relies on Javascript for compressing data. Compressing a 25MB large chunk takes about 1-2 seconds with most browsers (Chrome, Safari, Firefox, ...). IE11 takes over 40 seconds for exactly the same operation.
I thought IE11 was just painfully slow, so I decided to enable the profiler and see what is happening. To my surprise the same chunk was compressed in 2-4 seconds. Although still slower than Chrome, it was way faster then before.
Steps to reproduce:
Go to www.transferxl.com.
Open the developer console (F12).
Add a (compressible) file that is larger than 25MB.
Transfer the file and watch the console
You'll see a message how long it takes to compress the chunk of data.
Refresh the window (while still on www.transferxl.com).
Start the profiler.
Add a the same file again.
Transfer the file and watch the console
You'll see that the same block is now compressed much faster. You can also try it in reverse order. Results are stable. With the profiler on IE seems to compress 10-20 times faster then without the profiler.
Does anyone know what could be the problem? The profiler output doesn't show anything alarming. Has anyone else seen this issue?
I have tried doing exactly what you asked, and the uploads took less than 2 seconds on both Google Chrome (39.0.2171.65 m) and Internet Explorer (11.0.9600.17420). It appears as if Microsoft may have released this fix in one of their more recent updates. As far as I have seen, nothing of this sort was mentioned in the changelogs. Yes, I ran IE with the profiler disabled. I presume that the issue may have been caused by IE assigning process priority to scripts running with the profiler attached, since the profile also needs to function and render its output (supposedly) without affecting the functioning of the page itself. The compensation does not noticeably affect the computer's processor consumption in any way, but somehow just utilizes existing memory that has been allocated by IE prior to opening the profiler.
The "Dynamically updated data" demo on the HighStock website seems to leak memory in the current version of Google Chrome (24.0). I've tried it on Mac OS X 10.8.2 and Windows 7 (64-bit). I also tried Safari 6.0.2 on OS X, and both IE9 and Firefox 18 on Windows 7. The leaking only seems to happen in Chrome, and it always happens.
Given that this is a fairly prominent demo, I would have expected it to work well. But given enough time, it crashes in Chrome, giving the "Aw, Snap" error page. It can take a long time in the demo as written, but if you click the jsFiddle link and change the setInterval() call to 100 ms instead of 1000 ms, the leak is fairly obvious. A real application with multiple series and a decent amount of data can crash Chrome in just a few minutes.
Note that while data is being added continuously, the "shift" parameter in addPoints() is always true, meaning that old data is being discarded just as quickly. So the memory usage should be fairly constant--and on browsers other than Chrome, it is.
I'm not sure how to tell if this is a Chrome bug or a HighCharts one. And I haven't found a useful workaround. A conclusive answer to either aspect would be much appreciated.
Inspired by Mark's comment, I decided to try different versions of various things. First I tried the bleeding-edge versions of jQuery and HighStock. Chrome 24 (stable) still leaked. Then I tried Chrome 23 since it worked for Mark on Fedora, but it still leaked on Mac OS.
Then I tried the Chrome Canary build, 26.0. It worked, with no leaks! It exhibited the classic garbage collection pattern of building up a few dozen megabytes excess memory usage, then falling back down to "normal", every few seconds. So that's good news. The bad news is that Chrome Beta, 25.0, still leaks. So if other users of HighCharts experience this issue in the next couple months, they'll need to either use an "unstable" version of Chrome, or just a different brand of browser.
Are there any add-ons for Firefox that I can use to find out with part of the JavaScript causes memory leaks?
I've got nothing for firefox, but the webkit inspector in Chrome has a profiler built in that is great for that kind of thing.
As an added bonus it also shows you all browser events such as repaints, so you can engineer your code to have the least impact on the browser.
Use Drip.exe / IEleak, I used it a lot to search for memory leaks!
Other hits:
jQuery itself prevents a lot of memory leaks!
Test your code with http://jslint.com
There is a tool by Microsoft itself, but I don't know it is up to date: http://blogs.msdn.com/b/askie/archive/2008/12/31/javascript-memory-leak-detector-for-internet-explorer.aspx
There is also integration with Visual Studio: http://berniesumption.com/software/how-to-debug-javascript-in-internet-explorer/
There is a good article about mem leaks http://www.ibm.com/developerworks/web/library/wa-memleak/
http://www.debugbar.com/?langage=en
The best memory profiler I've found is for IE (supports even IE6 ;-). Give it a go - you will be surprised how good it is:
http://ajax.dynatrace.com/ajax/en/