In JavaScript we have two types of data types, primitive types and objects. Whenever you define a variable in JavaScript, the JavaScript engine allocates a memory to it. Show
Depending on whether the variable is an object or a primitive value such as string, number etc., it will be stored either in Stack or a Heap Data structure.
Any data type value which is immutable is stored on a Stack data structure since it’s size is known during compilation phase. Mutable data types such as Objects, Arrays are stored on a Heap data structure and a reference to the Object or array is stored on the stack data structure. The language itself doesn't specify where or how anything is stored, though most will be stored in RAM. Some integers may get stored in registers -- but not all processors even have registers. But in short, no, you can't take direct control of any of that. In fact, the language is designed to remove you from any of the low-level details. To access direct memory, you need to use a language like Low-level languages like C, have manual memory management primitives such as Regardless of the programming
language, the memory life cycle is pretty much always the same: The second part is explicit in all languages. The first and last parts are explicit in low-level languages but are mostly implicit in high-level languages like JavaScript. In order to not bother the programmer with allocations, JavaScript will automatically allocate memory when values are initially declared. Allocation via function callsSome function calls result in object allocation.
Some methods allocate new values or objects:
Using valuesUsing values basically means reading and writing in allocated memory. This can be done by reading or writing the value of a variable or an object property or even passing an argument to a function. Release when the memory is not needed anymoreThe majority of memory management issues occur at this phase. The most difficult aspect of this stage is determining when the allocated memory is no longer needed. Low-level languages require the developer to manually determine at which point in the program the allocated memory is no longer needed and to release it. Some high-level languages, such as JavaScript, utilize a form of automatic memory management known as garbage collection (GC). The purpose of a garbage collector is to monitor memory allocation and determine when a block of allocated memory is no longer needed and reclaim it. This automatic process is an approximation since the general problem of determining whether or not a specific piece of memory is still needed is undecidable. Garbage collectionAs stated above, the general problem of automatically finding whether some memory "is not needed anymore" is undecidable. As a consequence, garbage collectors implement a restriction of a solution to the general problem. This section will explain the concepts that are necessary for understanding the main garbage collection algorithms and their respective limitations. ReferencesThe main concept that garbage collection algorithms rely on is the concept of reference. Within the context of memory management, an object is said to reference another object if the former has access to the latter (either implicitly or explicitly). For instance, a JavaScript object has a reference to its prototype (implicit reference) and to its properties values (explicit reference). In this context, the notion of an "object" is extended to something broader than regular JavaScript objects and also contain function scopes (or the global lexical scope). Reference-counting garbage collectionThis is the most naive garbage collection algorithm. This algorithm reduces the problem from determining whether or not an object is still needed to determining if an object still has any other objects referencing it. An object is said to be "garbage", or collectible if there are zero references pointing to it. For example:
There is a limitation when it comes to circular references. In the following example, two objects are created with properties that reference one another, thus creating a cycle. They will go out of scope after the function call has completed. At that point they become unneeded and their allocated memory should be reclaimed. However, the reference-counting algorithm will not consider them reclaimable since each of the two objects has at least one reference pointing to them, resulting in neither of them being marked for garbage collection. Circular references are a common cause of memory leaks.
Internet Explorer 6 and 7 are known to have reference-counting garbage collectors, which have caused memory leaks with circular references. No modern engine uses reference-counting for garbage collection anymore. Mark-and-sweep algorithmThis algorithm reduces the definition of "an object is no longer needed" to "an object is unreachable". 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 an improvement over the previous one since an object having zero references is effectively unreachable. The opposite does not hold true as we have seen with circular references. Currently, all modern engines ship a mark-and-sweep garbage collector. All improvements made in the field of JavaScript garbage collection (generational/incremental/concurrent/parallel garbage collection) over the last few years are implementation improvements of this algorithm, but not improvements over the garbage collection algorithm itself nor its reduction of the definition of when "an object is no longer needed". The immediate benefit of this approach is that cycles is no longer a problem. In the first example above, after the function call returns, the two objects are no longer referenced by any resource that is reachable from the global object. Consequently, they will be found unreachable by the garbage collector and have their allocated memory reclaimed. However, the inability to manually control garbage collection remains. There are times when it would be convenient to manually decide when and what memory is released. In order to release the memory of an object, it needs to be made explicitly unreachable. It is also not possible to programmatically trigger garbage collection in JavaScript — and will likely never be within the core language, although engines may expose APIs behind opt-in flags. Configuring engine memory modelJavaScript engines typically offer flags that expose the memory model. For example, Node.js offers additional options and tools that expose the underlying V8 mechanisms for configuring and debugging memory issues. This configuration may not be available in browsers, and even less so for web pages (via HTTP headers, etc.). The max amount of available heap memory can be increased with a flag:
We can also expose the garbage collector for debugging memory issues using a flag and the Chrome Debugger:
Data structures aiding memory managementAlthough JavaScript does not directly expose the garbage collector API, the language offers several data structures that indirectly observe garbage collection and can be used to manage memory usage. WeakMaps and WeakSets
In typical explanations of
If
As a rough mental model, think of a Warning: This is not a polyfill nor is anywhere close to how it's implemented in the engine (which hooks into the garbage collection mechanism).
As you can see, the For more information on their APIs, see the keyed collections guide. WeakRefs and FinalizationRegistryNote: All variables with an object as value are references to that object. However, such references are
strong — their existence would prevent the garbage collector from marking the object as eligible for collection. A One use case for
Due to performance and security concerns, there is no guarantee of when the callback will be called, or if it will be called at all. It should only be used for cleanup — and non-critical cleanup. There are other ways for more deterministic resource management,
such as For more information on the API of Where are variables stored when your JavaScript programs execute?Variables initialized with the var keyword are stored in the memory of the current Execution Context's VO as a property, and initialized with the value undefined . This means, unlike functions, trying to access the value of the variable before it is defined will result in undefined .
How are arrays stored in memory JavaScript?In Javascript, an array is a Hashtable Object type so the interpreter doesn't need to keep track of physical memory and changing the value of an element doesn't affect other elements as they're not stored in a contiguous block of memory.
Does JavaScript use stack or heap?A stack is a data structure that JavaScript uses to store static data. Static data is data where the engine knows the size at compile time.
|