Garbage collection of objects as arrays of arrays - javascript

Here I've read a simple delete is not enough to free the memory allocated for an object.
I have an Object containing some subOjects, in the form: MyObject[idx]['foo']. Is there a way to free the memory used by Objects containing subObjects?
If I make a MyObject[idx]=null is this enough for garbage collection?

I've read a simple delete is not enough to free the memory allocated for an object
delete has nothing to do with memory management in the first place. The text you are referring to also clearly states this.
With regard to memory MyObject[idx]=null and delete MyObject[idx] have the same effect. If the object that MyObject[idx] has pointed to is not being referenced anywhere else then the garbage collector will eventually remove that object from memory.
Usually you won't come into a situation where you actually want to free memory. You may delete properties or remove elements from arrays when you no longer need them. But that's not the same.

Related

When does garbage collection actually get executed in Javascript? [duplicate]

Is there any way to control when Javascript performs garbage collection? I would like to enable it to perform garbage collection at certain times to ensure the smooth operation of my web site
Javascript doesn't have explicit memory management, it's the browser which decides when to clean it up. Sometimes it may happen that you experience un-smooth rendering of JavaScript due to a garbage collection pause.
There are many techniques that you can apply to overcome glitches caused by garbage collection (GC). More you apply more you explore. Suppose you have a game written in JavaScript , and every second you are creating a new object then its obvious that at after certain amount of time GC will occur to make further space for your application.
For real time application like games, which requires lot of space the simplest thing you can do is to reuse the same memory. It depends on you how you structure your code. If it generates lots of garbage then it might give choppy experience.
By using simple procedures: This is well know that new keyword indicates allocation. Wherever possible you can try to reuse the same object by each time by adding or modifying properties. This is also called recycling of object
In case of Arrays, assigning [] is often used to clear array, but you should keep in mind that it also creates a new array and garbages the old one. To reuse the same block you should use arr.length = 0 This has the same effect but it reuses the same array object instead of creating new one.
In case of functions: Sometimes our program needed to call a specific function more time or on certain intervals by using setInterval or setTimeout.
ex: setTimeout(function() { doSomething() }, 10);
You can optimize the above code by assigning the function to a permanent variable rather than spawning each time at regular intervals.
ex : var myfunc = function() { doSomething() }
setTimeout(myfunc, 10);
Other possible thing is that, the array slice() method returns a new array (based on a range in the original array,that can remain untouched), string's substr also returns a new string (based on a range of characters in the original string, that can remain untouched), and so on. Calling these functions creates garbage if not reutilized properly.
To avoid garbage completely in JavaScript is very difficult, you could say impossible. Its depends, how you reuse the objects and variables to avoid garbage. If your code is well structured and optimized you can minimize the overhead.
Unfortunately, there is no way to control WHEN the garbage collection takes place but with the proper formation of objects, you CAN control how quickly and cleanly it happens. Take a look at these documents on Mozilla Dev Net.
This algorithm assumes the knowledge of a set of objects called roots
(In JavaScript, the root is the global object). Periodically, the
garbage-collector will start from these roots, find all objects that
are referenced from these roots, then all objects referenced from
these, etc. Starting from the roots, the garbage collector will thus
find all reachable objects and collect all non-reachable objects.
This algorithm is better than the previous one since "an object has
zero reference" leads to this object being unreachable. The opposite
is not true as we have seen with cycles.
Why not keep references to all your objects until you want them to be GC'd?
var delayed_gc_objects = [];
function delayGC(obj) { // keeps reference alive
return delayed_gc_objects[delayed_gc_objects.length] = obj;
}
function resumeGC() { // kills references, letting them be GCd
delayed_gc_objects.length = 0;
}
you can perform some changes to improve your memory use, like:
don't set variables on loops
avoid using of global variables and functions. they will take a piece of memory until you get out
JavaScript is a garbage-collected language, meaning that the execution environment is responsible for managing the memory required during code execution.
The most popular form of garbage collection for JavaScript is called mark-and-sweep.
A second, less-popular type of garbage collection is reference counting. The idea is that every value keeps track of how many references are made to it
GC follows these algo, even if you manage to trigger the GC, it will not be guaranteed that it will run immediately, you are only marking it
garbage collection (GC) is a form of automatic memory management by removing the objects that no needed anymore.
any process deal with memory follow these steps:
1 - allocate your memory space you need
2 - do some processing
3 - free this memory space
there are two main algorithm used to detect which objects no needed anymore.
Reference-counting garbage collection: this algorithm reduces the definition of "an object is not needed anymore" to "an object has no other object referencing to it", the object will removed if no reference point to it
Mark-and-sweep algorithm: connect each objects to root source. any object doesn't connect to root or other object. this object will be removed.
currently most modern browsers using the second algorithm.

Experimenting with auto-removed items from WeakSet/WeakMap (via garbage collection) in Node.js when .size doesn't exist?

#1. Workaround for lack of .size property?
In JavaScript, I've never used either WeakSet or WeakMap before, and I don't know that much about garbage collection in general (I'm a PHP + JS developer, so this is the first time I've really needed to think about garbage collection). But I think I have a good use case for WeakMap right now. So I'd like to at least start experimenting with it.
The main thing I want to confirm in my experiments is the automatic removal of objects when they've been garbage collected. This would be easy to test if I could just access a WeakSet.size / WeakMap.size property on the instances to check their size, but they don't exist on the "weak" versions.
If possible, I'm guessing that the results could vary seeing that the size is going to depend on whether the garbage collector has run yet. But that's ok, as none of this experimentation code will be used in production... I just want to confirm that I actually understand how garbage collection and WeakSet/WeakMap are working. The idea of using this feature without being able to test (and therefore fully understand) it makes me very uneasy, and I'm concerned that I'll end up finding out about memory leaks when its too late (in production).
Are there any workarounds or alternatives to deal with the lack of WeakSet.size and WeakMap.size... at least just for debugging/testing/learning purposes?
If not a .size workaround, is there maybe a way to check the memory usage of my WeakMap collection instances? That would be just as useful, as that's where the main concern is.
The only thing I can think of right now is checking the memory of the entire Node.js process... which doesn't seem very reliable to me.
#2. What is .length for?
Also I'm a bit confused about why there is a .length property on the class constructor/instance prototype of both WeakSet and WeakMap (not on your instances of them).
According to:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap
...both pages say that .length is:
The value of the length property is 0.
Are they literally just hard-coded to the number 0 at all times? What's the point of that?
Searching for either "WeakSet.length" or "WeakMap.length" on Google (including the double quotes for exact results) yields no further information, only about 20 results for each, which are just mirrors of the MDN pages.
The size won't be available for either WeakSet or WeakMap since their keys are just references to objects, and these are handled by the Garbage Collector. Since the collector cannot be manually controlled (or shouldn't be), it will free the memory of these objects, once they are no longer referenced, at any point during runtime. The workaround you suggest to implement a way to see its current size would not be effective nor recommended considering this.
The length is there since both WeakSet and WeakMap are created through their prototype counterparts. Given how the collector will take care of clearing the object reference at any point,
As for experiment with them, you can try them out in Chrome and expose the garbage collector (and manually calling it) to see how the WeakMap clears itself after an object reference is lost (explained in this answer). Otherwise, you may still see the reference within the WeakMap or WeakSet since devtools usually prevents the garbage collector from running.

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.

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)

How to free up the memory in JavaScript

I'm working with canvas and its ImageData object which contains a huge amount of data (millions of integers). So working with a few arrays already takes a lot of memory (up to 300MB). Is there a way to free up the memory of some array when it's unnecessary? I'm trying to assign undefined to that variable. Is it right?
If the variable persists (e.g. it's global or part of some persistent data structure) and the data it points to is large and you want that data to be eligible for garbage collection, then you are correct to assign something small to that variable. undefined or null or "" will all work. What you're doing is clearing the reference to the large data so that it will be eligible for garbage collection. If nothing else in your javascript has a reference to that data, then it can be freed by the garbage collector. If anything else has a reference to it, then it cannot be freed.
For example, if you had a 10,000 element array held in a global variable:
var largeDataArray = new Array(10000);
And, you had filled most elements with data, then you could allow that memory to be eligible for garbage collection by assigning it some other value like:
largeDataArray = null;
or if you still want it to be an array:
largeDataArray = [];
Note: variables that themselves go out of scope (like local variables in functions that aren't part of a lasting closure) or variables in objects that themselves go out of scope do not have to be manually cleared. When they go out of scope or when the parent object is deleted, the data contained within will also be eligible for garbage collection.
So, the clearing of a variable only needs to be done when you explicitly want to free data that is held in a long lasting variable and it's usually only relevant to worry about this when the data is large or you have a lot of them that add up to multiple megabytes of data (memory use is of higher concern at lower levels on smartphones than in desktop browsers).
JavaScript has automatic memory management. Memory containing objects which are no longer referenced will be eligible for garbage collection, unless you have a memory leak. There is generally no need to manually assign undefined to variables.
If your program is using too much memory, you should shrink the arrays to get rid of elements you no longer need. See Array.pop, Array.shift, and Array.splice.

Categories

Resources