Do DOM objects get garbage collected in javascript? - javascript

var domElementReference = $(document.createElement('div'));
Will the DOM element get destroyed if I don't actually insert it on the page (once domElementReference gets out of scope)?
If not: If I have a constructor-function that creates DOM elements, is there an automatic way to clear them in javascript?
What I tought was to append them on an element, and then use
myChildNode.parentNode.removeChild(myChildNode);
But than again I have to manually call the function when the object is getting out of scope, and it kind of messes up the whole 'garbage-collection' idea. Any patterns to
automatically destroy the object?

If the elements haven't been inserted into the DOM and no other references exist, then yes they will be garbage collected, just like any other variables.
Modern browsers use a Mark-and-sweep algorithm for garbage collection, this means the garbage collector will look for and garbage collect objects that are unreachable. If you create elements in your function, but don't assign a reference elsewhere or don't insert them into the DOM, then they will be eligible for garbage collection after the function completes.
There is no need to manually try to free memory in JavaScript, it is all handled implicitly.
MDN documentation for Memory Management in JavaScript.

Related

Why can WeakMap and WeakSet work with 1 element, but cannot work with the whole data collection at once?

I've read that WeakMap and WeakSet don't support working with the entire data collection at once, which means that keys(), values(), entries(), size() and loops are inaccessible for these type of collections. It's written that the reason of that behaviour is that the developer cannot know exact moment when the garbage collector will work.
The source
...technically it’s not exactly specified when the cleanup happens. The JavaScript engine decides that. It may choose to perform the memory cleanup immediately or to wait and do the cleaning later when more deletions happen.
How do I see this? For example, the first element in the WeakMap/WeakSet data collection has been removed. But it may happen that the garbage collector hasn't cleared it from the storage yet. Hence, deleted element can be used in loops, methods that work with whole collection. To avoid this behaviour, all of these methods and loops aren't supported by these data collections.
let weakMap = new WeakMap();
let obj = {};
//adding some elements
weakMap.set(obj, 255);
weakMap.set({name: `Rita`}, `Rita`);
//deleting the first element
obj = null;
//we can't use loops for the whole collection
//why? because deleted element with `obj` key can still exist in data storage
weakMap.get(obj); //it's theoretically possible that deleted element with `obj` key still
//exists in the data storage, garbage collector hasn't reached it yet
It's completely understandable. But what about referring to a single element? By the way, it's completely allowed for these type of collections. But, in fact, we also don't know exact moment when the garbage collector will work. As I see, it means that element can be deleted, but because of the fact that garbage collector hasn't reached it yet, it still can be displayed.
It turns out that limited functionality of these collections cannot secure bugs in the form of output of deleted elements? Am I correct?

Ensuring object can be garbage collected

My node/javascript program receives lots of messages.
Each time a message is received I create a new object, passing it message content.
Within the new objects constructor, the object does a bunch of stuff, including some mongo operations with callbacks.
When the operations that are performed within the object constructor are complete, the object is no longer needed or wanted.
After some experiments involving complexity (i.e. storage of the object in an array element or as a property of a 'master' object and then deleting it, I tried the simple approach.
var x = new DisposableObject(message);
delete x;
This seems to work fine. There may be many instances of DisposableObject in existence at any time. DisposableObject is created and does everything expected of it in tests.
I am assuming that when I delete 'x' that this does not affect the object itself, just the reference to it that is contained in 'x'. The objects callbacks occur and all is good.
So four questions:
Will this simple mechanism allow the garbage collector (node/V8) to get rid of the object?
Is there some awful trap door awaiting my code because I am doing this?
Is there any issue with multiple instances of DisposableObject floating around waiting for callbacks when there is no active reference left to them in my program?
Is there a better way to create the objects, then make sure they can be garbage collected after all their operations are completed?
Javascript uses a nongenerational mark-and-sweep garbage collector, in javascript objects are automatically garbage collected when they are no longer needed , so you need not worry about garbage collection.
but you have to keep these points in mind (from this answer):
what you are trying with delete does not really delete an object, delete is only effective on an object's properties. It has no effect on variable or function names., Use delete statements whenever you create an object using a new statement, pair it with a delete statement. This ensures that all of the memory associated with the object, including its property name, is available for garbage collection. The delete statement is discussed more in “Freeing Objects.”
Use the var keyword. Any variable created without the var keyword is created at the global scope and is never eligible for garbage collection, presenting the opportunity for a memory leak.
In case of global variables, Global variables are never disposed of by the GC in the sense that a global variable will always exist. Setting it to null will allow the memory that it references to be collected. the memory used by the object will be eligible for collection. but The variable still exists though, and it simply references null(some more here)

Why is it faster to access the DOM through a cached variable?

I am trying to improve my knowledge of javascript and while searching for some "best practices", someone pointed out to me that it is faster to cache the DOM document and then access it through that var instead of accessing the document object directly.
You can see the results here, on an edit I made on jsperf: http://jsperf.com/jquery-document-cached-vs-uncached/3 (edit: the title holds "jsquery" because that was the original test, my edit contains vanilla javascript, the framework makes no difference)
This really makes me curious. Basically I am introducing a new variable into the equation, how can that make things faster instead of slower?
As far as I know, "print a" should be better than "b = a; print b" (figure of speach)
What's different in this case?
document is not like an ordinary Javascript variable. There's no telling what odd magic is happening under the covers when accessing its attributes, especially the DOM, which may be created on demand from internal browser structures.
I believe I found an explanation here (the emphasis on the last part is mine):
Store pointer references to in-browser objects. Use this technique to
reduce DOM traversal trips by storing references to browser objects
during instantiation for later usage. For example, if you are not
expecting your DOM to change you should store a reference to DOM or
jQuery objects you are going to use when your page is created; if you
are building a DOM structure such as a dialog window, make sure you
store a few handy reference to DOM objects inside it during
instantiation, so you dont need to find the same DOM object over an
over again when a user clicks on something or drags the dialog
window.If you haven’t stored a reference to a DOM object, and you need
to iterate inside a function, you can create a local variable
containing a reference to that DOM object, this will considerably
speed up the iteration as the local variable is stored in the most
accessible part of the stack.
So, if I understand correctly, caching the DOM in a local variable makes it easier to access in the memory stack, therefore increasing the speed of execution.

Node Cloning and Removing

What happens when a cloned node is not attached to any DOM. Suppose I have a JavaScript code Clone a DOM element every time it's method is called.I need this object temporarily, I don't need to add it to DOM component. But I am worried if it creates performance issue in client side so I am wondering what happens to the object cloned by javascript.
As soon as the JavaScript Engine detects you are done with that object its garbage collector will clean it up for you. As long as the object isn't in the global scope or is able to be referenced it will be cleaned on a garbage collector pass.
It depends on how you are assigning the clone, but it's possible they could accumulate in memory.
No code = no idea.

Can jQuery.data cause a memory leak?

Would the following piece of code create a memory leak.
According to the jQuery documentation use of the data function avoids memory leaks. It would be useful to confirm whether the following is safe.
var MyClass = function(el) {
// Store reference of element in object.
this.element = $(el);
};
// Store reference of object in element.
$('#something').data('obj', new MyClass('#something'));
Obviously the code as it stands would take up extra memory as long as the DOM element is still connected to the DOM. But I'm guessing you're asking whether it would continue using extra memory after the DOM element is no longer in use.
Update: Thanks to Joey's answer (which he has since deleted), I spent some time reading up on memory leaks in javascript, and it appears my assumptions in the paragraph below are incorrect. Because DOM elements don't use pure garbage collection, a circular reference like this would normally prevent both the DOM element and the javascript object from ever being released. However, I believe the remainder of this answer is still correct.
Without a deep knowledge of how javascript engines implement garbage collection, I can't speak authoritatively on the topic. However, my general understanding of garbage collection makes me think that your code would be "safe" in the sense that after the #something element is removed from the DOM, the resulting MyClass object would only have a reference to an object that has no other connections. The graph algorithms of the garbage collector should be able to identify that the DOM element and its MyClass object are "floating in space" and unconnected to everything else.
Furthermore, jQuery goes out of its way to strip data and events that are associated with a given DOM element once it is removed from the DOM. From the documentation:
jQuery ensures that the data is removed when DOM elements are removed via jQuery methods, and when the user leaves the page.
So assuming you use jQuery consistently, you would only have a one-way reference once the object is removed from the DOM anyway, which makes it that much easier possible for the garbage collector to know it can get rid of these objects.
So as long as you don't have something else referencing the MyClass object once the DOM element is removed, you shouldn't have a memory leak.
I suppose it depends on the Javascritp engine.
You have have the question precisely enought to perform a test. I added a long string in the object and ran the potential leak in a large loop.
As a result, I don't think in leaks in IE8 nor in Chrome.
But I could not reproduce these leakeage patterns either.
This can lead to a memory leak.
the theory of jQuery.data method may use A Data inner class to cache data for the dom element.
of course,when you remove the cache data,jQuery will unreference the data.
but the inner cache is a increasing array,when you you it ,it will go upon.
so ,in the end,there will be very big cache array,which will lead memeory leak.
In a long run web app,this may leak memory crash.
The data attribute only stores string values.

Categories

Resources