In Determing if a SQL select returns an empty set asynchronously? I ended up trying to use an object's method's as an event handler. Using the normal "this" of the object doesn't correspond to the method's object in the context of an event handler (why, not sure, beyond my current simplistic understanding of javascript, my guess is due to scoping of variable names?).
As I mentioned in my previous Q, from http://w3future.com/html/stories/callbacks.xml, their solution is to basically have each object provide a "var me = this" variable. My question is, does this create a circular reference that will prevent the object from being garbage collected?
If so, is there a better way to accomplish the task?
thanks.
Yes, that will create a circular reference.
However, it won't cause any problems.
Modern Javascript garbage collectors can handle circular references perfectly well. (except, in IE6, for references crossing between DOM and user objects)
If s and everything that references it either leaves reachable scope or is manually deleted, then it will get garbage collected. If you delete s but statement.executeAsync still has reference to the callbacks, the references to me will stay around too.
delete s;
s; //undefined
//This will still contain the function reference
statement.executeAsync.handleResult;
delete statement; //Now s and me should be garbage collected
If you just clear each handler individually instead of the statement object, that would work too. Assuming you can reach each callback individually.
delete statement.executeAsync.handleResult;
delete statement.executeAsync.handleError;
delete statement.executeAsync.handleCompletion;
This also depends on how executeAsync is implemented. If the internal implementation doesn't store the callbacks in a scope that lives past the final callback, then it would get cleaned up with you deleted s
Related
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.
A colleague of mine always sets their jQuery variables to null, to effectively dispose them, once they're finished with, e.g:
var bigThing = $(body);
// ...
// Do some stuff
// ...
bigThing = null;
Is that really necessary?
If you encapsulate your code into functions thats unnecessary as after the function finishes the local variables will be killed anyway when no reference of them is used elsewhere.
Holding onto a selector/variable (caching) might have some positive effect tho if you need to select the same thing over and over again versus selecting it only once and keeping the variable.
Short answer: no that's hardly ever necessary if you're using jQuery.
It depends on what you did with it. If you didn't attach any event handlers to the DOM Node, the garbage collector will clear it when it's no longer referenced.
But even if you did attach event handlers, jQuery will take care of them in functions like .remove() and .empty() by detaching all event handlers for you. So as long as you use jQuery to interact with the DOM, you're safe.
Without jQuery, if you've attached an event handler to the Node, the GC won't clear it, even after you've removed the Node from the DOM tree and you no longer have any references to it. This is because the DOM Node contains a reference to a JavaScript object (i.e. the event handler) and vice versa. This creates a cyclic reference across two separate systems; something most garbage collectors have trouble with.
For further reading I point you to Douglas Crockford's article on Memory Leaks.
It's not necessary but good habit to remove reference and release the memory
Though not entirely necessary, this can be done to ensure that the GC clears it in its next run (which it'll anyway do for all allocations to which you don't have even 1 reference).
In your example though, the $(body) object (the jquery extended object, not the DOM body object) will be cleared if you set bigThing to anything else (not necessarily null)
Javascript has its own garbage collector. So, it appears that you don't need to explicitly dispose of the objects.
But due to various reasons, like bad implementation of garbage collector etc., it may happen that their are some memory leaks.
By nullifying them explicitly, you specify to the browser that this memory has to be cleared in next garbage collection.
In conclusion, though it is not necessary to do this, it will be a good practice to nullify the JQuery/javascript objects.
var Obj = function(){}; var X = new Obj();
will X = null properly clear memory?
Also would this be equivalent?
var Obj = function(){};
var X = {};
X.obj = new Obj();
delete(X.obj);
EDIT
It would seem that although deleting X.obj would NOT immediately clear memory, it would help the garbage collection. If I don't delete X.obj, there would still be a pointer to an object and so the GC may not clean it up.
Although I'm picking #delnan's answer, if you're reading this you should def also catch Benubird's article.
I also notice I accidentally wrote delete(X) originally instead of delete(X.obj) - sorry.
The short answer is that you don't. delete simply removes a reference (and not in the way you try to use it, see the above link - delete is one of those language features few people actually understand), nothing more. The implementation clears memory for you, but it's not your business when (and even if, strictly speaking - this is why one shouldn't rely on finalizers in GC'd languages that offer them) it does. Note though:
Only objects that can be proven to be unreachable (i.e. no way to access it) to all code can be removed. What keeps references to whom is usually fairly obvious, as least conceptually. You just need to watch out when dealing with lots of closures, as they may capture more variables than you think. Also note that circular references are cleaned up properly.
There's a bug in old (but sadly still used) IE versions involving garbage collection of JS event handlers and DOM elements. Google (perhaps even SO) should have better material on my memory.
On the plus side, that means you won't get dangling pointer bugs or (save of course the aforementioned pitfalls) memory leaks.
No, that will not clear memory.
Read this:
http://perfectionkills.com/understanding-delete/
No - Javascript runs GC when it feels like it.
The Delete method only deletes the reference - not the object. Any other references would be left out in the open waiting for the garbage collector.
JavaScript has its own GC, and it will run around and clean things up when nothing refers to them anymore.
I still think it's a good practice to null objects.
Deleteing an object also helps the GC because it will see something dangling, and say "I'm going to eat you because you're all alone (and now some cynical laugh)".
You should look at Deleting Objects in JavaScript
Even though there's a GC, you still want to ensure your script is optimized for performance as peoples computers, browsers, and fricken toolbars (and the number of them), will vary.
Generally speaking, memory management in Javascript is user-agent-specific. The basics of the garbage collector are through reference-counting. So, by setting a reference to null (using the delete keyword or by explicit assignment), you can assure yourself that a reference will be cleaned up, IF the object does not have any references that will live outside of its creation scope. That being the case, the GC will have already cleaned up any objects or variables whose scope has ended without your explicitly setting it to null.
There are some things to take care of, though - circular references are easy to create in JS, especially between a DOM element and an object. Care must be taken to clear (or not create in the first place) references to and/or from DOM elements within objects. If you do create a to/from reference related to DOM, be sure to explicitly clean them up by setting the references to null - both on your object and on the DOM element. Simply setting a parent object to null is not sufficient if there are child objects with references to/from DOM or localStorage because those references will live on, and if there was any reference from the child to the parent, then the parent will live on in memory because of that reference.
Web pages can actually leak trash in your memory this way - after you navigate away, the circular references keep objects and DOM elements in memory until you've restarted the browser!
An article on the subject: http://docstore.mik.ua/orelly/webprog/jscript/ch11_03.htm, and another detailed look: http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/53038.aspx
JavaScript memory is generally handled similarly to Java - I mean there is (or there should be) a garbage collector which would delete the object if there is no references to it. So yes, simply "nullifying " the reference is the only way you should "handle" freeing memory, and the real freeing is the JS host part.
For example, I have this code:
{a: 42}
After this line was executed, I think the object is stored somehow in the memory, I'm wondering how can I get it, in some tricky way?
No.
You can't do this.
Any decent js interpreter will destroy it with the garbage collector.
No: once you lose all references to an object, you cannot recover it and the GC will collect it.
No.
Anonymous objects are intended to work this way. If you need to retrieve an object later on, you should simply name it. (I assume you are asking this question out of curiosity and not out of neccessity).
As soon as an object has no existing references to it, the garbage collector should destroy the object, as is confirmed by this page:
ECMAScript uses automatic garbage
collection. The specification does not
define the details, leaving that to
the implementers to sort out, and some
implementations are known to give a
very low priority to their garbage
collection operations. But the general
idea is that if an object becomes
un-referable (by having no remaining
references to it left accessible to
executing code) it becomes available
for garbage collection and will at
some future point be destroyed and any
resources it is consuming freed and
returned to the system for re-use.
This would normally be the case upon
exiting an execution context. The
scope chain structure, the
Activation/Variable object and any
objects created within the execution
context, including function objects,
would no longer be accessible and so
would become available for garbage
collection.
I have a script which creates a user-defined object like this:
obj = new Tree();
This object is always present and interacting with the user.
I want to create a button on the page which, if pressed, should retrieve this object, make some changes to the object and call some methods.
If this were a DOM object, I could have used any of getElementById() or getElementByTagName() etc. However, this object is created in the script and I need to access it in another part on user intervention. Further, making the object global is not an option. Does anybody know how it may be done?
You can attach objects to window if you are defining them inside a different scope than the one you want. This should make it "global". Although I highly suggest fixing your scoping so that var obj exists where it needs to, and not anywhere else.
window.myObj = new Tree();
You will need to make the object accessible from some part of the event handling function. So while making the object itself global is not an option (which is a good move), presumably there's some top-level object which is global to the page for your application? Something like a namespace object, or an OurPageScript object, something like that? In that case, setting the tree as a property of this object will allow for it to be dereferenced later by the event handlers.
If you absolutely cannot have any variables that are accessible from anywhere across the page, things get more tricky. In that case, you will need by definition to provide the event handlers with a reference to your object (because they won't be able to get it themselves). The only way I can think of to do this is to rewrite the handlers every time the object changes; setting them to a closure that includes the object, and invokes the actual handler with this object as a parameter.
A middle ground might be to give the appearance of a global variable by declaring that all event handlers will be invoked in a closure environment where var_tree is defined. That way you wouldn't need to actually mutate the handlers, just repackage them in an appropriate closure whenever the object changed.
(I presume your question was solely about getting access to the object; once the handlers have this, they can modify it and call methods with no further gotchas.)