Interesting observation with IE memory management and javascript - javascript

In windows, when an application is minimised the OS frees up memory associated with application by placing the data within a page file. Other garbage collection may also execute.
In the case of internet explorer running my javascript app I find that if the memory usage starts at 60mb then minimising the browser reduces the memory to 17mb. Maximising then takes it back up to 40mb
A 20mb gain.
My application makes heavy use of javascript and I suspect that IE is forcing a garabage collection of the objects which are no longer referenced.
Via javascript (IE only) you can force garbage collection via:
CollectGarbage()
So, if I call this method (without minimising the screen) I only reclaim a meg or 2.
If I call this via the event queue:
setTimeout(CollectGarbage, 1000)
I reclaim around 3 meg
My application is designed to run all day and so memory management is very important.
Anybody got any ideas how to force IE to clean up its memory to the same extent that a manual minise does?
Suggestions of programatically minimising the browser will be scoffed at!
Cheers :)

Use the delete keyword to undefine the variable/property, saving you memory. More here.
But if you only need to lose a reference to an object property, just set it to null and wait for the next collection.
Be careful using closures and lambda functions, as they have traditionally been memory hogs and sources of leaks. See Understanding and Solving Internet Explorer Leak Patterns.

Related

Doing a full garbage collection from Javascript in Electron (Chrome / nodejs)

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.

Is this js heap graph worrying? How can I fix it?

I have recorded the performances of an angular 4.4 app and I think that what the Chrome dev tools returned me about the js heap could be worrying, but I honestly lack on this subject.
I don't understand the straight drop at ~20000ms, the straight line soon after and the other drop at ~60000ms: what are they due to? Are those behaviours normal or do they means that something should be fixed?
The incline means that the page was allocating memory in the JS heap. This is normal.
The drops mean that the browser freed up memory in the JS heap that was no longer needed. This is called garbage collection. That's normal, too. Nothing alarming about that.
In general, if you see that the total amount of memory is progressively increasing after each garbage collection event, then that's a warning sign that you have a memory leak. The memory leak pattern usually looks like this:
Source
As you can see from the graph, if you leave the page running for long enough, eventually it will use up all of the computer's memory, causing the computer to run slowly, or crash.
See Fix Memory Problems for more techniques for analyzing memory usage.

Is there a way to find JavaScript memory leaks within tests?

I just finished writing tests for JavaScript application and I was using Jasmine for the first time. Everything works fine, but I still need to test if application has some memory leaks within. Is it even possible to programmatically check it within my specs? Maybe there is some additional library for this?
Chrome has a non-standard extension of the window.performance API -- (window.performance.memory), where you can measure memory usage.
In order to enable precise memory statistics, you must use this flag: --enable-precise-memory-info
But you also need to force GC to tell whether memory is retained after your test. Because CG doesn't happen instantly.
With Chromium browser, you can run it with a special command flag to expose a method to force GC:
chromium-browser --js-flags='--expose_gc'
This gets you access to the method window.gc().
As I know there is no automatic way to find source of javascript memory leak. Javascript memory leaks is realy nasty thing on which you can waste a lot of time. Recently I was developing very large enterprise web solution as a single page application with almost 1mb of minimized self-written code. Suddenly we realized that our application is leaking hard. I tryied hundreds of technics to find the source of memory leak and the easiest way for me is to use google chrome profiler, take heap snapshot and compare different heap snapshots. Here is more information how to do it :
https://developer.chrome.com/devtools/docs/javascript-memory-profiling
Have a nice week with debugging memory leaks in your app, hope it will take less time that in my case. :)

JavaScript: should I worry about memory leaks in 2011?

The topic of memory leaks in JavaScript is not brought up often. However, I stumbled upon this article, written in 2007. The authors state:
Internet Explorer and Mozilla Firefox are the two Web browsers most
commonly associated with memory leaks in JavaScript.
Should I still be worrying about JavaScript memory leaks in 2011? If so, what should I be careful about?
A good javascript developer would be aware of various design patterns that can lead to memory leaks and you'd avoid coding anything that could turn in to a leak in pretty much all the pages you code.
For example, keeping a reference to any DOM object in a javascript variable will keep that DOM object alive in memory even if it's long since been removed from the DOM and you intended for it to be freed.
Practically speaking, leaks are only significant in some circumstances. Here's where I specifically worry about them:
Anything I'm doing repetitively on a timer, particularly if it can be left running for a long time. For example, if you have a slideshow that might just loop forever, you have to make absolutely sure that nothing in the slideshow is an accumulating leak of either JS or DOM objects.
A web page that works like an app and the user may stay on the same page for a long time, interacting with the page, doing ajax calls, etc... For example a web mail app might be open and on the same actual browser document for a very long time doing lots and lots of user and server interactions.
A web page that regularly creates and destroys lots of DOM elements like something that regularly uses ajax to fetch a bunch of new HTML.
Places where I don't really worry about leaks:
A web page that doesn't have a long running set of interactions the user can do.
A web page that doesn't stay on screen very long before some other page is loaded or this page is reloaded.
Some of the key things I keep an eye out for.
Any lasting JS variables or properties that contain references to DOM elements when DOM elements are being created/destroyed.
Any properties of a DOM object that contain references to other DOM objects or references to JS objects that contain reference to other DOM objects (this can create circular references and cross references between JS/DOM that some older browsers have trouble freeing).
Any large data structures that I load for temporary use. I make sure that no references to these large data structures are every kept around.
Any data caches. Make sure nothing really large gets cached that you don't want cached. Make sure all caches that get used repeatedly don't accumulate forever and have some sort of aging mechanism to get rid of old objects.
Yes, memory leaks are definitely a problem in JavaScript, since circular references are indeed possible. A very common source of memory leaks is the use of closures. As an example, consider:
var outerFunction = function(param1, param2, param3) {
var innerFunction = function() {};
return innerFunction;
};
It is possible for the above to leak the parameters, since innerFunction holds a reference to the scope in which it was constructed, which includes the parameters to that frame.
While it is easy for these sorts of things to go unnoticed on many desktop computers, where there is plenty of RAM, this is actually something that can be very obvious on devices with limited RAM (e.g. a mobile phone or a set top box). As an anecdotal example, a couple websites that shall remain unnamed used to crash on me quite frequently when visited from my TV, which has very limited RAM.
Note that these problems are with the JavaScript code written by web developers. Memory leaks in the underlying JavaScript interpreters, while possible, are far less of an issue, and isn't something that web developers can reasonably concern themselves about, since that's the job of the browser writers.
NO.
More complete answer: maybe. The fact you are asking so vaguely is a strong signal that you personally are unlikely to need to worry.
In practice, the vast majority of JavaScript code simply doesn't worry about it, and doesn't need to worry about it because only in particular circumstances do memory leaks in pages end up affecting users. The browser and frameworks cover your arse pretty well.
There are only a few questions you need to answer:
Q: Are you supporting a rich single page application that uses JavaScript heavily?
If not, then don't waste your time worrying. If you (or your QA, or your clients) find a memory over-usage issue with a page then fix it when it comes up.
Q: Do you need to support mobile devices, and you have heavy javascript usage?
Mobile devices have limited memory and extra care needs to be taken.
If you ARE developing a JavaScript heavy application, and you need to worry about memory usage, then...
The issue of "dirty" references to objects that cause JavaScript objects and DOM objects to never get garbage collected is important to certain types of JavaScript applications. Caches that grow forever, unexpected global references, and unexpected references inside closures can be a problem.
The Heap Snapshot tool in Chrome's Web Inspector can help.
Here is a git project that has a useful writup and walks the javascript objects it can: https://github.com/tlrobinson/leakhelper
There are other tools that help you, but I wrote my own over time:
1. our framework marks deleted widgets, so I wrote code to walk all arrays and objects from window or document looking for the paths to delected objects (javascript code can't walk closures but it definitely helped find some leaks).
2. Another trick I used was when widget x was deleted, I do a x.leakhelper = window.createElement('leakhelper') and setAttribute the oid of the widget, but not add the element into the document. If the DOM element is not garbage collected then the widget must have a dangling reference to it somewhere. In IE use window.collectGarbage() to force the GC, and use sIEve to detect the leaked DOM element (I found sIEve to be really useful).
Obsolete question: Do you need to strongly support either IE6 or IE7 AND you use JavaScript heavily? Most of the scary leaks you used to read about only occur in < IE8. If you are supporting IE6 or IE7 then you need good luck and perseverence (all frameworks leak, and it is hard to write code that doesn't even with a perfect framework - I ended up writing my own IE leak prevention code for our production use for IE6/7 users). The IE6/IE7 leaks can last even after you close your page - which is why they are so nasty.
Well, people still use old versions of IE. So beware of circular references, because IE has severe problems with that. I believe the common mistake in that regard is to reference an HTML element in a closure that is inside an event handler to that element. Just set the variable referring to the element to null and it'll be fine.
It really depends on 2 things -
Average run-time expectation of your application. Simple jquery lightbox or carusel on main page of online shop can leak (and often does, because, they are coded so badly), but nobody will notice (because the page is closed or refreshed within couple of minutes or less). But Node.js server, full-ajax social network, browser game or online IDE - can run for hours or even days non-stop.
I/O complexity of your application. The more you touch DOM, XHR/network, files, DOM/UI events, the more times you redraw the screen (be it canvas, html or svg) - the bigger is risk for leaks, memory hogging (which is NOT a leak) and running into browser bugs.
Good thing for you is - those two things correlate with each other. So, you either write shovel-code like no tomorrow, or engineer for performance, endurance, and robustness.
p.s.: if you have to support IE8-, you are not in 2011, yet. So you just have to worry, like in good old times.

How can I avoid causing memory leaks in Firefox?

It seems that there is a lot of information on memory leaks in IE and how web developers can avoid them, but I can't find much on avoiding leaks in FF. I've found lots of random tips on how end users can tweak their preferences, or tips for extension developers, but little on what I can do as a web developer to make sure my pages don't leak. Am I missing something? It seems lazy to just blame it on the user and say "you've got too many extensions". Or are the major patterns the same as in IE -- circular references and all that?
Also, if anyone knows of any tools to troubleshoot leaks in FF, that would be great. I found this:
https://addons.mozilla.org/en-US/firefox/addon/2490/
But it's apparently just for chrome and extension development.
Outside of the design patterns to favour the only truely safe way is to test your pages thoroughly. To monitor the memory usage of the browser Task Manager is alright but Process Explorer provides more accurate results.
JavaScript is one cause of memory leaks but be careful with flash movies on pages too. Our content team added a movie from our design department that used a thrid party transition affect and this swallowed 10Mb every 20s or so. Just watching the movie loop through it was obvious in TaskManager to see the memory jump when the affect occured and the it never quite release it all back.
You can force to run a Garbage Collector in FireFox. The Garbadge Collector will destroy & release objects that are not used anymore. The only possibility of "Leaking memory" with a Garbage Collector is not a "leak" but a reference which makes no sense: remove all references to objects that you don't want to use.
Read more on this page:
http://adblockplus.org/blog/different-ways-to-force-garbage-collection
A bunch of what you read about how to avoid memory leaks in browsers is about how to avoid things that cause the browser to fail to reclaim memory that it should reclaim.
However, a more substantial problem in many cases is about Web pages holding on to objects that they don't need anymore. It's only the browser's job to reclaim things that are no longer "reachable" -- that is, things that the script / page can't get to anymore. If you're accumulating objects in an array and not removing them when you're done with them, memory usage will go up as the array gets bigger, and there's nothing the browser can do about that.
To phrase that another way: that's an issue of a memory leak in the Web page rather than in the browser. And the tool you want for that is a memory profiling tool to examine the objects that are reachable in your page, so you can tell whether there's stuff in there that you should no longer be holding on to. Writing such a tool for Firefox has been on my list of things to do for a while, but I haven't gotten around to it yet. I think there might be some ongoing work on writing one that integrates into Firebug.
I don't know if there is specific information for Firefox, but the generic tips still apply.
I suggest that you closely examine all loops and recursive functions. Re-use existing objects over creating new ones, and ensure that temporary objects and primitives exit scope so that they can be freed.

Categories