Are global variables cleaned by garbage collector in Node? - javascript

In the following JS code, will example1 or example2 be ever cleaned by the garbage collector? Will their memory be ever released by the GC? I am dealing with memory leaks and I have a few such instances in my code.
example1 = 'Outside a function'
function sample(x){
example2 = 'Inside a function'
}
sample(1)
From what I understand is neither of the variables will ever be cleaned by Garbage collector because they are treated as global variables. Might sound like a trivial question but finding memory leaks is like finding a needle in a haystack

The heap has two main segments, the New Space and the Old Space. The New Space is where new allocations are happening; it is fast to collect garbage here and has a size of ~1-8MBs. Objects living in the New Space are called Young Generation. The Old Space where the objects that survived the collector in the New Space are promoted into - they are called the Old Generation. Allocation in the Old Space is fast, however collection is expensive so it is infrequently performed .
You need understand few thinks, like:
1 - The garbage collector builds a list of "roots". Roots usually are global variables to which a reference is kept in code. In JavaScript, the "window" object is an example of a global variable that can act as a root. The window object is always present, so the garbage collector can consider it and all of its children to be always present (i.e. not garbage).
2 - All roots are inspected and marked as active (i.e. not garbage). All children are inspected recursively as well. Everything that can be reached from a root is not considered garbage.
3- All pieces of memory not marked as active can now be considered garbage. The collector can now free that memory and return it to the OS.
So about your questions:
From what I understand is neither of the variables will ever be cleaned by Garbage collector because they are treated as global variables.
Might sound like a trivial question but finding memory leaks is like finding a needle in a haystack
You are correct.

Related

Do I have to delete the node or the garbage collector does the work in JS?

To delete the last node of the circular link list in JS, I will traverse to the second last node and I will link the second last node with the first node, the last node is now disconnected from the chain. Now is it necessary to delete the last node like in c++, doesn't garbage collector of JS does the work ?
JavaScript handles freeing memory through the use of the garbage collector. As long as there are no longer any references pointing to an object, where all references have moved out of scope, it will be garbage collected. You don't need to worry about freeing memory yourself.
One thing to note in your use case is the limitation of circular references. Specifically when you have a situation where object A references object B, A->B; and object B references object A, B->A. Even if both A and B move out of scope and nothing else references them, they will not be garbage collected as both object still have "1 reference" from eachother.
I believe "most" modern browsers and runtime environments now support Mark & Sweep, and if they're not accessible should also be garbage collected, solving this issue.

When is javascript code considered garbage for the GC

So i've been getting into the more advanced parts of javascript. Right now im learning about memory, memory leaks and garbage collecting. Many examples on the web just exaplain what the garbage collector is , but i am having trouble finding one that tells me when the code is considered garbage for the garbage collector.
So far I've read "When there's no longer a reference pointing to an object". Is that the only case? What exactly do they mean by that.
Thanks in advance.
It's better to see it as code being reachable or not from the roots, and roots are values that are inherently always reachable, such as global variables. The garbage collector in JS uses a "mark and sweep" algorithm, where it starts from the roots and visits each reference and their references and so on. Once it's visited, it gets marked as being visited/reachable together with all reachable references from there, and will not be visited again.
You can have references pointing to objects, which maybe also have references to other objects, but once they can never be reached anymore from the root, they form a sort of unreachable island of references. They will never get visited and will finally be sweeped away by the garbage collector.
There are also several optimizations done. For example some objects get created and do their job once and then die off. Those new ones get cleaned up very aggressively and fast. If they are used for longer periods of time they will be considered old, and will be visited less often to check if they should be garbage collected.

Are WebGL objects garbage collected?

In JavaScript memory that I allocated (e.g. an ArrayBuffer) gets freed up when I don't have any reference to it anymore by the GC as I understood that right?
WebGL objects like Buffers or Textures are associated with a memory block on the GPU as allocated by gl.bufferData() or gl.textureImage2D().
I'm wondering: if I give up my last reference to a WebGLTexture or WebGLBuffer object, does it get garbage collected with its GPU memory block freed by the JavaScript VM automatically?
Yes
From spec
Note that underlying GL object will be automatically marked for deletion when the JS object is destroyed
But you should notice that the object would probably not destroyed at the time you give up the last reference, so it's still a good practice to call deleteBuffer.
Copied from this answer: Are WebGLTextures garbage collected?
with the word WebGLTexture changed to WebGLObject
Yes and no.
Yes they are garbage collected. But garbage collection happens whenever the browser decides to collect them. From the POV of most browser JavaScript engines the WebGLObject object is a tiny object that just contains an int so it has no easy way to know of any special pressure to collect it. In other words when the GPU runs out of memory the JavaScript garbage collector, which has no connection to the GPU, has no way of knowing that it needs to free these tiny WebGLObject objects in order to free up texture memory. It's only looking at CPU memory.
This is actually a well known problem of garbage collection. It's great for memory. It's not so great for other resources.
So, yes, WebGLObject objects are garbage collected and yes the texture/buffer/renderbuffer/program/shader will be freed but practically speaking you need to delete them yourself if you don't want to run out of memory.
Of course the browser will free them all if you refresh the page or visit a new page in the same tab but you can't count on the browser to garbage collect WebGLObject objects (textures/buffers/renderbuffers/programs/shaders) in any useful way.

JavaScript - large for loop, should I release objects?

I have a for loop that iterates over a fair few items.
At the start of each iteration I use the same var newObj = new ...
However, I'm wondering, is this completely replacing that object each time or should I be releasing it at the end of each iteration.
If I should release - how do I do release?
For example - say x is a large number (10.000 as a high example)
for (var x = 0; x<10000; x++) {
var newObj = new someThing(x, y, z)
newObj.dance()
newObj.andDanceMore()
//Should I do some kind of release here - or am I replacing it each time
}
Thanks.
in javascript you don't have to worry about "releasing" allocated memmory,
from the great MDN docs
High-level languages (such as JS) embed a piece of software called "garbage
collector" whose job is to track memory allocation and use in order to
find when a piece of allocated memory is not needed any longer in
which case, it will automatically free it. This process is an
approximation since the general problem of knowing whether some piece
of memory is needed is undecidable (can't be solved by an algorithm).
basically the general behavior of the G.C is when an object has zero references to it - It can be garbage collected.
in the case you reffering to, each time you assigning a new value to var newObj, the G.C detect that there are 0 reffernces to it and garbage collected it - releasing it -
Short answer: no.
Slightly longer answer: There is no manual memory management in JavaScript. It is a garbage collected language. Each time the GC is launched (and you have no control over when that happens), all objects that have no references will be automatically collected, effectively freeing the memory they occupied.
Further reading: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management
Do you know what Garbage Collector is? If not, you could find very nice blogposts googling "node.js garbage collection".
In brief:
1) When you override the variable value (or local variable is being dropped with its scope), the object still remains in memory.
2) When Node.js decides to run garbage collector, your object will be wiped out from memory in the following cases:
2.1) There are no variables, containing it (actually pointing to it).
2.2) There are some variables/properties pointing to it, but the entire cluster of objects and closures with mutual links is identified as isolated.
3) You may force garbage collector run (How to request the Garbage Collector in node.js to run?), but in regular cases you do not need this.
4) Difference between let and var, mentioned in comments, does not affect your case. Yes, let is more local than var, but what? If Node.js drops let variable quitting the loop, or you override any variable (var, let, property - whatever) with new value, the result is the same.
var newObj
Will be executed only once.What the program did is that Constantly assigned to newObj in the loop, objects that are not referenced will be recycled by GC.

What methods are there to prevent the Javascript gc from running as little as possible?

I'm learning Javascript, and in the various texts the authors will speak of javascript using a mark and sweep gc to deallocate objects from memory. They will also speak of how if you set the value a variable references to null it will delete the reference to that value, allowing the allocated space to be set for gc. This SO answer says that you can remove the allocated memory and the reference by setting the value the variable contains to null and then to undefined, effectively removing the allocated space from the heap (if I understood it correctly).
So my question is this: Is it possible to write javascript in such a way that you can eliminate gc?
(If it is implementation specific I would like to know if it is possible on v8, though if this is possible on rhino or other js implementations that would be of immense use too)
Judging by projects like LLJS my request isn't too unreasonable, but I'm not entirely sure how the memory module does it.
I've always found it helpful if I explain why I'm asking so here it goes. I really like compilers, and I wanted to write a compile-to-js language that leveraged a static inferred typing system similar to SML. The reason why I wanted to write my own was because I wanted to utilize region inference to determine exactly when objects and variables come out of scope (as much as possible) and upon leaving scope remove it from the heap, thereby eliminating as much gc as possible. This is mostly a research project (read: because I can) so any resources on memory optimization in javascript would also be greatly appreciated!
EDIT: I guess another way to phrase it would be "Is it possible to write js in such a way that the gc will deterministically never run (as much as possible)? If so what techniques would be involved?"
I'm not looking per se for delete because that marks the element for deletion thereby invoking what I wanted to (try to) avoid, I was curious if the implementation's gc would run if I removed all references (and the value) associated with the variable.
Alternatively, paraphrasing from the referenced SO Answer:
x = foo;
x = null;
x;
Is x still on the heap?
It's not entirely clear what you're looking for.
The standard Javascript implementations have NO way of manually deallocating memory. You can remove a property with the delete operator, but that just removes the property from the object. It doesn't even free any contents that the property points to (that is left for garbage collection if there are no other references to that data).
Javascript was designed from the ground up to be a garbage collected language. It frees things from physical memory only when the garbage collector runs and that garbage collector finds objects that are unreachable (e.g. there are no references to those objects still in use). The language does not contain commands to free memory.
It is possible (in some JS implementations) to call the GC yourself rather than wait for the JS engine to run it, but it's still using GC to decide what to free.
Responding to the additional things you added to your answer.
To the best I know, javascript only cleans things up when the GC runs. Until then objects are marked such that the GC can see that there are no references to them anywhere, but they aren't actually freed until the GC checks and notices this. Further, local variables in a function scope are themselves a type of object and those are not freed until the GC runs and notices that there are no references to the function scope (in JS, a closure can maintain a reference to a function scope even after the function has completed).
So, in your code example:
x = foo; x = null; x;
x is still alive and occupying some space because it's still in scope and code could still reach it. It's contents will be null which presumably takes no extra space beyond the variable itself, but the space for the variable itself won't be freed until the function context it is in is found to be reference free by the garbage collector.
JS is a garbage collected language. That's when things are actually freed from the heap. There are no instructions in the language to free things anytime sooner.
The delete keyword will trigger garbage collection by the browser. Be aware that it deletes entire chains of objects unless you nullify object references.
var o = {...};
delete o;

Categories

Resources