If I have a map containing the ids of DOM elements and I want to de-reference an entry in the map, so the corresponding element can be picked up by garbage collector, what are the steps I should go through to make sure there is no memory leak? Should I delete or = null on the map entry? What do I need to do about the element itself?
(I assume by "map" you mean "object".)
To permanently remove a property and value from an object, use delete. Using null will have the effect of clearing the value, but retaining the property.
Both will allow the value to be garbage collected.
But to what you're trying to accomplish, if the map only has reference to an ID string, it will have no impact on the element itself. You need to drop all references to the element (in DOM and JavaScript) to ensure the element is garbage collected.
Related
I was checking the doc in MDN about garbage collection. When I come across the 'Real-life example' section, the term 'explicitly removed' in below statement confused me.
If the property is not explicitly removed or nulled, a reference-counting garbage collector will always have at least one reference intact and will keep the DOM element in memory even if it was removed from the DOM tree
Can document.removeChild fulfill the criteria of removing DOM element explicitly?
Can document.removeChild fulfill the criteria of removing DOM element explicitly?
The question indicates some confusion: there is no criteria to explicitly remove the DOM node. Removing an element from the DOM, either explicitly or implicitly (by removing an ancestral element from it descends), should make it available for memory collection assuming no reference to the removed element is retained in code. The property mentioned at the beginning of the quoted article refers to the div.circularReference property used in the example, whose value was set to div to create a circular reference back from the property to the element.
Explicitly removing "the property" could be achieved by deleting or changing the property's value, for example with
div.circularReference = null; // or
delete div.circularReference;
Removing the circular reference could be done before or after removal of div from the DOM. The good news is where the article says reference-counting garbage collector are no longer used in modern browsers.
Being a C developer, I feel the urgent need to free memory as accurately as possible. But after reading some posts about memory management in JavaScript I still have some questions about that topic. As far as I understand, there is a garbage collector that will automatically free the memory when an object isn't referenced anymore and the GC can find the time. So an object that is held in a local variable is very likely to be freed when the variable goes out of scope.
Let's assume I have some custom elements (tab control, data table, inputs etc.). The classes of those custom elements have member variables where several data for the specific element is stored. Also event listeners can be attached to the elements the custom element consists of.
Let's say I have following html markup:
<my-tabbar>
<my-tab id="myTab">
<my-input></input>
<my-dataTable></my-dataTable>
</my-tab>
</my-tabbar>
Now I want to remove <my-tab>. Is it sufficient to just do
var element = document.getElementById ("myTab");
element.parentNode.removeChild (element);
element = null;
Or do I have to dereference every object of the child elements and remove their event listeners?
Setting an object to null makes it an empty object. Once the object is out of scope, the GC (when it runs) will clear it up. Setting local objects to null won't do you any good.
Example:
function whatever()
{
var something = null;
console.log( typeof( something ) );
}
whatever();
Output:
"object"
For the removal of a child node, please see this:
Does removeChild really delete the element?
Source(s):
https://www.w3schools.com/js/js_datatypes.asp
It is sufficient to remove the element. You don't even have to set the variable to null afterwards – you can trust the JS engine to free the memory when it goes out of scope.
All:
I am new to DOM, I got one question about DOM reference, for example(suppose I use D3.js or jQuery):
var domelement = d3.select("div#chart");
d3.select("div#chart").remove();
console.log(domelement);
When I print domelement, it still show an Object in the console even though it has been deleted from the DOM structure.
So I am wondering, why this variable still has access to the DOM object?
How can I decide if a reference is invalid?
Thanks
So I am wondering, why this variable still has access to the DOM object?
You retrieved a reference to an object in memory and your variable will retain it for as long as you have it in scope.
You can mutate an object having a reference to it but you cannot destruct it (not in JS).
How can I decide if a reference is invalid?
There is no such a thing as "invalid" reference. If you want to check if the element is still mounted in the DOM - you can just try to search for it. If it's there - you'll find it, and you will not otherwise.
.remove() returns the value (like a return function in javascript). When you use console.log this value is printed but it no longer exists in the DOM. HTML elements can exist as data nodes in javascript (document.createElement).
In this state, they exists as data, but haven't been added anywhere where they'd be visible. .remove() cuts the element out of the body and returns it in its data form, then console.log prints it.
Do I have to destroy instances myself? ...if I don't assign them a variable...will they automatically go away?
new ImageUploadView();
vs
var Iu = ImageUploadView();
If there is no reference to an object in javascript, the garbage collector will clean it up.
The way the garbage collector works is it looks for javascript objects for which nobody has a reference to. If nobody has a reference to it, then it can't be used again, so it can be deleted and the memory it occupied reclaimed. On the other hand, if any javascript entity still has a reference to the object, then it is still "in use" and cannot be deleted.
In your first code example:
new ImageUploadView();
unless the constructor of the object stores away the this pointer into some other variable or object or creates some closure that causes references to the object to be held, then there will be no reference to this new object and it will be cleaned up by the garbage collector.
If you second code example:
var Iu = ImageUploadView();
as long as the Iu variable exists and stays in scope it will contain whatever the ImageUploadView() function returns. Note, the second example, is just executing a function and storing it's value. It is not necessarily creating anything. If ImageUploadView() just returns true, then that's all the Iu variable will contain.
The first method is fine. Assuming that the instance of ImageUploadView is appropriately cleaning up after itself, it will be collected by the garbage collector.
With large objects, it's not necessarily a good practice to assume that the browsers built in garbage collector will clean up once it's out of scope. You're better off to clear it ourself using "delete". For example:
delete MyImageUploadView;
Edit: it may be preferable to set the object to null if it isnt being referenced as a property.
Please excuse my question if it doesnt make much sense.
I am using javascript to create a dom element
to do that i create an object ( obj ={}) and fill out the properties as i go, one of which is the dom element to be created. once the element is created and appended to the document i do not need the object to occupy any space in the memory so i was thinking i should remove it.
how would i go about doing that?
thank you
The object's going to exist in memory as soon as it's in the DOM, and the obj property that holds it is really holding a reference to it, not a copy. So as far as I know, the memory required to keep the reference as a property of obj should be negligible. In which case I wouldn't worry about removing it at all.
here is how:
my_var = null;
//or remove it
delete my_var;
if you define you object as locale like
var obj ={}
it will be automatically undefined at the end of the function.