Do we need to “unset” variables in JavaScript? - javascript

Do we need to unset variables in JavaScript, and why?
For example in PHP it's recommended to unset all temporary variables in all kind of loops to keep memory free and avoid variables duplicates.
But anyways according to php - what's the benefit of unsetting variables? question:
Is it true that unsetting variables doesn't actually decrease the memory consumption during runtime?
-Yep.
So should we delete window.some_var;?
Or we should use some_var = null?
Or we should not unset variables to avoid additional CPU cycles?
UPD:
Related questions:
How to unset a Javascript variable?
How to remove a property from a javascript object

No, plus in some cases you can't delete variables in the global scope. Variables that are properly declared using the var keyword cannot be deleted (implied global variables can be deleted, on the other hand. Always use the var keyword to declare variables).
Also, javascript engines have this thing called garbage collector that automatically looks for variables that are no longer used or referenced somewhere when your code is 'running'. Once it finds one, it'll shove it off immediately into the Abyss (deletes the variable in the memory)

No, it is not necessary to delete variables when you’re done with them. If you have so many enormous, global variables that this is actually a problem, you need to rethink your design.
And yes, it’s also silly in PHP, and no, it has nothing to do with avoiding “additional CPU cycles”.
Specifically:
“Unsetting temporary variables in loops”
They’re temporary, and probably either a) integers or b) references that take up about as much space as an integer. Don’t bother.
“Avoiding duplicate variables”
Again – references. Setting things that are still referenced elsewhere to null is pointless.
If you feel like it’s clutter, that is a good sign that more things should be going out of scope (i.e. use more functions).
In most other cases that you haven’t mentioned, the engine is also smart enough to manage your stuff properly. Do not optimize prematurely.

David Flanagan answers this quite nicely in his book, JavaScript: The Definitive Guide:
The JavaScript interpreter performs automatic garbage collection for memory management. This means that a program can create objects as needed, and the programmer never needs to worry about destruction or deallocation of those objects. When an object is no longer reachable – when a program no longer has any way to refer to it – the interpreter knows it can never be used again and automatically reclaims the memory it was occupying.
This doesn't mean that memory leaks can't happen in JavaScript. Far from it. Circular (or cyclic) references are a frequent problem in browsers which implement reference counting, as documented here by IBM:
A circular reference is formed when two objects reference each other, giving each object a reference count of 1. In a purely garbage collected system, a circular reference is not a problem: If neither of the objects involved is referenced by any other object, then both are garbage collected. In a reference counting system, however, neither of the objects can be destroyed, because the reference count never reaches zero. In a hybrid system, where both garbage collection and reference counting are being used, leaks occur because the system fails to identify a circular reference. In this case, neither the DOM object nor the JavaScript object is destroyed. Listing 1 shows a circular reference between a JavaScript object and a DOM object.
If you're worried that your website contains a JavaScript memory leak, Google has a tool, aptly named "Leak Finder for JavaScript", which can help you find the cause.
Further reading: What is JavaScript garbage collection?

Related

can objects be marked not to be garbage collected?

I don't know too much about the JavaScript garbage collector, just that it attempts to manage references so that unreferenced objects can be periodically purged from memory. I was thinking about something that I thought might improve performance if it was feasible by the language implementers.
It would go something like this. In a file add a line:
"no gc";
This is similar to the use strict setting. It would mark everything defined in the file as not for garbage collection. I'm thinking this would be used in libraries like jQuery and underscore. All of the helper methods would be marked and stored in a separate area of memory that is not managed by the GC.
While I know this might end up keeping around stuff that is not ever used; it would at least isolate it from periodic GC process. So while we perhaps gobble up some extra memory, we at least lighten the load of GC processing.
I apologize for the naivety of this suggestion as I have never implemented GC. I am just wondering if this idea is feasible or if JavaScript somehow does this already.
if you want to keep them as cache then you have global scope.
In browser global scope is window,
hence consider if you dont want object X to never get garbage collected then simply you can write
window.nogc = X;
since window which is global scoped ,will be never garbage collected so its child references also wont be garbage colleted until we explicitly make it.
Garbage collection only runs when the thread is free. Nothing would be saved because GC only occurs when the system isn't busy.
So no, this isn't possible.
You can ensure that an object does not get collected by referencing it from a GC root, but not that it doesn't get processed by the GC.
The reason is that GC in JS VMs is usually implemented via Mark-and-Sweep, or a method that is functionally equivalent. The basic premise is that the GC goes through a cycle that goes like this:
The GC marks all objects in the heap as being "potentially available for release". This is usually done by a flag toggle which changes the interpretation of the existing marks on objects from meaning "need to keep" to "safe to release". So no actual iteration over the objects occurs at this stage. Telling the GC to "not mark" certain objects would actually require extra operations, not less.
The GC starts at the GC roots, and traverse through the reference tree, changing the mark of objects from "safe to release" to "need to keep". This is the "Mark" phase. GC roots can be global objects, the currently executing stack, pending callbacks on the event loop, etc. The tree-traversal itself can be done in various way as well, with DFS being the simplest.
The GC goes over all objects in the heap, and removes any that is still marked "safe to release". This is the "Sweep" phase. Many optimizations exist in this phase, which allows the GC to free memory used by a group of objects in a single operation. Nevertheless, this requires at least some level of iteration, over groups of objects, if not over objects themselves.
Now here's the issue with setting a "non-GC" arena: Suppose that an object in your "non-GC" arena was to reference a regular object. During the "Mark" phase, if that object is not marked, it would be released. That means that all of your "non-collectible" objects need to be GC roots in order to "keep" regular objects to which they refer. And being a GC root offers no performance advantage over being directly referenced by a GC root. Both must equally participate in the "Mark" phase.
The only alternative is for your non-collectible object to not be able to strongly reference collectible objects at all. This can be achieved by having your own binary heap, rather than using native JS objects. The binary data would not be interpreted as references, and the heap object would finish its marking phase in a single operation. This is what asm.js does: It preallocates a large array to act as its internal heap. To the VM, the entire array counts as one big object, and therefore no garbage collection is done on any data structures that are encoded within it. Using this method does have the flaw that you need to encode all of your objects and data structures into the heap's binary format, and decode them when you want to use them. When working with asm.js, this is handled by the compiler.
in JavaScript if you want to kill a object, you have to delete all the references.
let's say we have a object like this:
var myobj={ obj : {} };
and we want to GC the obj object, we have to do this:
myobj["obj"] = null;
delete myobj["obj"];
but if you define another variable referenced to that object, it won't be killed with those line. for instance if you do:
var obj = myobj.obj;
if you really want to delete the object, you have do the same for this variable:
obj = null;
delete obj;
then if there is no reference it would be killed.
in other word if you want to prevent your object from GC, create a reference some where and keep it private.

If you want force garbage collection on a variable in Javascript, is it better to set it as null or undefined?

I am developing an Android game using JS framework. I want to make sure that some of the objects are garbage collected once I am done using them. How do i force it? Should I use null or undefined?
You can't force garbage collection (not in any sane fashion).
If your variables aren't going out of scope automatically, just set them to null.
Best advice is to define them in scope that makes them eligible for garbage collection. This means don't use global variables that never become eligible for collection. Instead declare them as locals.
You could set it to null, and if that is then the last reference to that object, it will become eligible for garbage collection.
http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/
TGH's suggestion is the best though, I'd recommend that.
If you want force garbage collection on a variable in Javascript, is it better to set it as null or undefined?
Doesn't matter, you can even set it to another object you created: as long as the object originally referenced by the variable is no longer referenced anywhere, it can be garbage collected. Think of your object as "something being referenced by variables".
If no variables reference it, it can be garbage collected, and "putting another object into a variable" will make the variable no longer reference the previous object.
I want to make sure that some of the objects are garbage collected once I am done using them. How do i force it?
You can force major garbage collection to be triggered in a Node-based runtime (e.g. Electron or NW.js), by using the --expose-gc flag and running:
global.gc();
If your app/game is browser-based, in Chrome only you can use the --allow-natives-syntax switch (your users would need to pass this to Chrome themselves), and call:
%CollectGarbage();
Note: dead simple, but you might as well just do a window.location.reload() as a fallback, if you can easily continue from where you left off (e.g. reload the game into another level, if you will).
Remember, however, these calls won't screw around, and can block for whole seconds if there is a lot of garbage to collect. This can be ideal if you have determined pauses in your game, such as loading screens between levels, but tricky otherwise.
You might also want to consider using an object pool, with or without using manual garbage collection, to simply reduce garbage and improve performance.

Renaming the 'this' keyword

I'm concerned that I might be using a code pattern that leaks memory. Here's a pseudocode example:
window.user = new User();
user.getBasicInfo(function(basicInfo){
user.name = basicInfo.name;
user.getDetailedInfo(function(detailedInfo){
user.favoriteColor = detailedInfo.favoriteColor;
});
});
In other words, I'm not using the 'this' keyword to refer to the user object; I'm referring directly to the user object stored within the window object.
Obviously, the JavaScript 'this' keyword has given lots of people lots of trouble. I've seen some people rename 'this' to make it more clear as they descend a scope chain:
window.user = new User();
user.getBasicInfo(function(basicInfo){
var userInOuterScope = this;
userInOuterScope.name = basicInfo.name;
userInOuterScope.getDetailedInfo(function(detailedInfo){
var userInInnerScope = this;
userInInnerScope.favoriteColor = detailedInfo.favoriteColor;
});
});
Not as pretty, but it seems like the scope chain might be less convoluted in that case.
Can the first approach leak memory? Can the second? To avoid leaking memory, must I pass everything as a parameter (and never refer to objects outside of the current scope)?
The potential to "leak memory" is not something relevant to the question you seem to be asking. That is, neither of the approaches have implications on memory use, at least not in any way clear to me.
The reason you might prefer to make use of the this facility in your code is that you might want a population of objects. In your case, you're apparently using the object as a singleton, so it makes no difference. However, that's really a special case, and you'd quickly find that it doesn't work so well if you've got 100 "User" objects.
Preserving the value of this (and it's not really "renaming" this; it's copying its value into another variable) inside a closure could result in a memory leak, or rather, could be part of a larger memory-leaking setup, but it's not problematic in and of itself. Making copies of object references is something that happens all the time.
edit — the "leakage" problem with closures comes about when a combination of things happens:
Some objects are referenced by variables in the closure scope (not weird or harmful in and of itself);
Functions with references to the closure scope "escape" from a function call, either by being returned or by being exported via global state side-effects (like registering an event handler) (also not weird or harmful in and of itself);
The population of these exported functions grow, or the functions themselves allocate more room when they're invoked and preserve references to the space allocated in the closure, or the exported functions end up directly referenced by DOM nodes (this is particularly a problem in IE).
Really, JavaScript doesn't have any unique problems with memory leaks that any language with real closures has. For a vast amount of actual JavaScript software in this world (utility code wired into web pages), it's pretty rare that memory leakage is a problem, I suspect, though the IE issue with DOM references has probably crashed a few browsers over the years (which probably hardly surprised the hapless users).
I don't like pushing frameworks on people, but it's definitely true that framework authors must worry about this stuff. Trusting in your framework to keep the DOM clean by making sure you only attach event handlers and data to the DOM via framework facilities is therefore a Good Idea.
It doesn't appear that you have any circular references in your code, so I wouldn't worry about memory leaks. You're not setting objects equal to other objects as far as I see ( http://jsfiddle.net/Akkuma/UTL3B/ as a quick example how it could lead to memory leaks).
Here are a few references on memory leaks
http://www.ibm.com/developerworks/web/library/wa-memleak/
http://www.javascriptkit.com/javatutors/closuresleak/index.shtml
http://javascript.crockford.com/memory/leak.html
Additionally, you can use Chrome's Heap Snapshot tool to be able to tell whether or not you are having memory leaks worth worrying about.
JavaScript's this is not the same this like Java's or C#'s. It represents the current context of something being executed.

Javascript variable reuse?

Is it OK to reuse variables for different data types in terms of performance and memory usage ?
What happens to old data, is it garbage collected immediately after type casting ?
It's OK to reuse variables, although unless you're doing some crazy things (say so in the question) with the amount of variables you're using, you probably should not reuse them too liberally in this way. It's considered good coding practice in general to have a variable declared to point to a specific thing, and use a different variable when you want to refer to something else.
"Variables" in Javascript are just references. They're not inherently expensive-- they don't take up more space than their text in the code and a few bytes in memory pointing to somewhere else. If you reuse a variable name by setting the reference to something else (or null/undefined), then the GC will know that that original reference is detached and know that it can be collected.
The GC in whatever browser or environment you're using will choose when to actually run the collector based on lots of factors.
Full disclosure: I have no knowledge of the internals of any particular JavaScript engines. I'm going from general principles of VMs and interpreters.
Usually, variable names just refer to other memory locations. So, whether you remove an old variable (which happens when it goes out of scope) and introduce a new one, or replace the current contents with a new object, doesn't matter much in terms of memory allocation.
Garbage collection might be different in each implementation. Immediate garbage collection is difficult; the only way I can think of doing it involves reference counters, and it's tough to make that work even for cyclic data structures. So, most garbage collectors in the wild do non-immediate collection cycles where, each time, a whole bunch of data gets removed. The cycles might, for example, be run automatically when memory use goes above a certain threshold within the engine (but it'll usually be more refined than that).
JavaScript is a loosely-typed language, and can store any datatype in any variable (even reused ones).
If you are combining types, though, you should check them periodically using the typeof keyword to ensure they are the type you think they are (for instance, trying to perform a mathematical operation on a string will concatenate or break, depending on the situation).
Furthermore, JavaScript variables stick around as long as they are within scope. Once a scope is left, the variables within it are destroyed (eventually - it's automatic and transparent). As far as garbage collection on reassigned variables, the old value is destroyed as soon as the new value is assigned.

Is it good practice to delete no longer used objects and variables in JavaScript?

In my code I use an object and variables inside a function. When in that function I no longer use the object and variables I delete it:
delete myObject;
delete myVar;
Is it good practice?
Does it give speed?
My JavaScript is server-side on smart.joyent.com.
Is it good practice?
No. In fact it is disallowed in the new ECMAScript Fifth Edition ‘strict mode’:
When a delete operator occurs within strict mode code, a SyntaxError is thrown if its UnaryExpression is a direct reference to a variable, function argument, or function name (11.4.1).
If you really must, you can instead =null the variable to free up any object it referenced for garbage collection, but it's almost never going to result in any appreciable improvement in performance.
Deleting properties of long-lived objects to free now-unused referenced objects can be a good idea, especially in the case of breaking DOM cycles to prevent memory leakage in IE. Deleting local variables inside a short-lived function isn't sensible.
I'm not sure what engine your server is using, but client-side engines typically employ garbage collection, and I wouldn't be surprised if your server environment does as well. Unless you have an extremely particular situation, most attempts of manual cleanup are probably going to be on par with (or working against) the garbage collector.
In summary, I would bet you see absolutely no difference in performance. This is a good example of micro optimization.
And also instead of using delete method, It seems that Firefox 3 allows script to invoke garbage collector with:
Components.utils.forceGC
See https://developer.mozilla.org/En/Components.utils.forceGC
Other browsers may provide similar functions too. (except IE, i don't think it provides.)
It is not generally considered necessary but in extreme, high memory situations is may be something you should look into. I do feel that its use prior to profiling and performance testing to be premature optimization.

Categories