I've heard that in JavaScript, primitive types are stored on the stack and that objects are stored on the heap. Is that true for all cases even for values inside of a function's execution scope? Moreover, are all globally scoped variables and functions stored on the global object (window in the browser) in JavaScript and is that considered to be the "heap" or part of the heap? Or are the primitive types themselves stored on the stack and reference types on the heap and then the identifiers are added as properties to the global objects and point to those values on the stack/heap?
There is no heap and no stack. JavaScript's memory model is very abstract. How things end up in your computers memory is totally up to the engine. Given that modern engines perform a lot of optimizations, values might end up in different regions of the memory even in different optimization stages, so one really can't tell.
Related
I read a lot of articles that say "v8 uses stack for allocating primitive like numbers".
I also ready about the CG works only for the heap allocation.
But if I combine the stack allocated variables with the closure, who is in changed to free the stack allocated variable?
For example:
function foo() {
const b = 5;
return function bar(x) {
return x * b
}
}
// This invocation allocate in the stack the variable `b`
// in the head the code of `bar`
const bar = foo()
// here the `b` should be freed
// here `b` is used, so should not be free
bar()
how it works?
How can bar function point to b if b lives in the stack?
How is the [[Environment]] built here?
(V8 developer here.)
I don't know where this myth is coming from that "primitives are allocated on the stack". It's generally false: the regular case in JavaScript is that everything is allocated on the heap, primitive or not.
There may be implementation-specific special cases where some heap allocations can be optimized out and/or replaced by stack allocations, but that's the exception, not the rule; and it's never directly observable (i.e. never changes behavior, only performance), because that's the general rule for all internal optimizations.
To dive deeper, we need to distinguish two concepts: variables themselves, and the things they point at.
A variable can be thought of as a pointer. In other words, it's not in itself the "container" or "space" where an object is allocated; instead it's a reference that points at an object that's allocated elsewhere. All variables have the same size (1 pointer), the things they point at can vary wildly in size. One illustrating consequence is that the same variable can point at different things over time, for example you could have a loop over an array where element = array[i] points at each array element in turn.
In modern, high-performance JS engines, function-local variables are usually stored on the stack (regardless of what they point at!). That's because this is both fast and convenient. So while this is technically still an implementation-specific exception to the rule that everything is allocated on the heap, it's a fairly common exception.
As you rightly observe, storing variables on the stack doesn't work if they need to survive the function that created them. Therefore, JavaScript engines perform analysis passes to find out which variables are referenced from nested closures, and store these variables on the heap right away, in order to allow them to stay around as long as they are needed.
I wouldn't be surprised if an engine that prefers simplicity over performance chose to always store all variables on the heap, so it wouldn't have to distinguish several cases.
Regarding the value that the variable points at: that's always on the heap, regardless of its type or primitive-ness (with exceptions to the rule, see below).
var a = true --> true is on the heap.
var b = "hello" --> "hello" is on the heap.
var c = 42.2 --> 42.2 is on the heap.
var d = 123n --> 123n is on the heap.
var e = new Object(); --> the object is on the heap.
Again, there are engine-specific cases where heap allocations can be optimized out under the right circumstances. For example, V8 (inspired by some other VMs) has a well-known trick where it can store small integers ("Smis") directly in the pointer using a tag bit, so in this case the pointer doesn't actually point at a value, the pointer is the value so to speak. An alternative trick is called "NaN-boxing", it's used e.g. by Spidermonkey and has the effect that all JS Numbers can be stored directly in the pointer (or technically the other way round: everything's a Number in this approach, and pointers are stored as special numbers).
As another example, once a function gets hot enough for optimization, an optimizing compiler may be able to figure out that a given object isn't accessible outside the function and hence doesn't need to be allocated at all; if necessary some of the object's properties will be held in registers or on the stack for the part of the function where they are needed.
So, to summarize the above:
"All primitives are allocated on the stack" is incorrect. Most primitives are allocated on the heap.
Sometimes, an engine can avoid allocations (of both primitives and objects), which may or may not mean that the respective value is briefly held on the stack (it could also be eliminated entirely, or only ever held in registers). Such optimizations never change observable behavior; in cases where doing the optimization would affect behavior, the optimization can't be applied.
Variables, regardless of what they refer to, are stored on the heap or on the stack or not at all, depending on the requirements of the situation.
JavaScript Example:
Suppose I do this:
var i;
And never use i anywhere else in the program. Will it be allocated any memory?
Or if I use, say i=2; after some lines.... will it be allocated memory at this point, or is the memory allocated during the creation of i?
C# example:
Suppose I do this:
dynamic i;
And never use i anywhere else in the program. Will it be allocated any memory (and if it will be, when? During compilation?)?
Or if I use, say i=2; after some lines.... will it be allocated memory at this point, or is the memory allocated during the creation of i, or is it allocated during compilation?
Also, would there be any other differences regarding memory allocation in the two examples above except the differences that arise due to the fact that JavaScript is an interpreted language and C# is a compiled language?
In C#, the expression:
var i;
can't be compiled in the first place; if we consider instead:
int i; // or dynamic i;
then that can be compiled and may or may not be retained, but it depends on whether it is a field (object variable) versus a local (method variable). Fields are not removed; however, the compiler is free to remove local variables as it sees fit. Whether it chooses to do so can depend on a lot of things, but most notably: whether you are doing an optimized release build, versus a debug build. Even if a local variable is clearly both written and read, the compiler can still remove it if it chooses - of course, the value will still exist on the stack, but not in a reserved location.
When the Javascript interpreter parses var i; and then executes the containing scope, it has to store the fact somewhere that the i variable is now defined in the current scope. Futures references in this scope will access this particular variable in this scope. Though implementation details are left to the implementor, the variable i is likely added to a particular scope object and thus has to consume some memory.
It is possible that if the variable is not referenced and it is in a contained scope without the use of things like eval() that the JS engine may be able to optimize it away. Whether or not it actually thinks it can do that and actually does so would have to be discovered by testing or studying of the source code.
Individual variables like this would likely consume only very small amounts of memory. For this to be of major consequence, you would likely have to have thousands of these.
In my code I was to deleting custom-objects. I realized, we can not delete objects which are declared using 'var'. (after reading this documentation Delete operator).
Most of my objects are declared and initialized using 'var'. They can't be deleted in single delete statement(unless I loop through it and delete each property.)
I can set them to 'null'.
My custom objects are relatively bigger in size (may block considerable chunk of memory.
For better memory management and performance should I use 'properties' or 'variables' to store my objects? Will it make a difference?
Please provide any references for better insight on 'properties' and 'variables' in javascript.
globalProp = {//can be deleted, it is a 'property' to global object.
'name': 'Mia',
'age': 34,
'sex': 'F'
};
var globalVar = {//can not be deleted with delete statement, it is variable of global object
'name': 'Lia',
'age': 25,
'sex': 'F'
};
(In above code, we can refer to globalProp as 'window.globalProp' but can't refer to globalVar as window.globalVar.)
Have fiddle
JavaScript has runtime and garbage collector with some complex cleaning and managing algorithms, any try to interfere or speed them will proably do the opposite, resulting some runtime penalty. it is the best to leave the memory managment to the underlying runtime.
however, there are some points that you might want to consider:
1) avoid global variables as much as possible. this is a good advice for any language that support global/static variables. global variables means global references with no scope - the referenced object will live on as long as the (global) reference holds it. this danger increases even more if the global variable is an array or object which keeps on appending children to itself.
this is the common case which leads to a memory leak in managed languages
2) avoid cyclic references - don't make one member variable point to a different object, and that object holds a member which points to the first object. this will make a hard time for the garbage collector.
3) write clean, simple, maintainable code. this may seems as unrelated preach, but an easier, short, maintainable code will probably enhance the interperter/compiler ability to optimize the code.
4) don't assume nothing about how the code affects the speed. there are so many layers down there that you can't simply assume anything. benchmark the code to get real facts.
5) don't optimize unless you need to (you probably don't).
so for your question : declare anything with var as much as possible. declaring a variable with var will make them local - when the function ends the reference will get out of scope and the GC can start determine the destruction time for the object earlier. declaring your object without var will make them global - it is unclear when will the GC decide to delete the object, thus slowing things down.
and as you know - declaring variables global can lead to many bugs, keep things scoped. don't use delete. it's just wrong.
I want to know what is the best way of accessing a JavaScript object, dot operator or []:
data.property or data["property"]?
Both are more or less the same, except in Safari in which case dot notation is significantly faster.
You're much better off concentrating on DOM manipulation, DOM size, and CSS complexity as major sources of performance problems in Javascript applications.
That said, if you are doing a lot of property access in a loop, a local variable will be much faster than either property access or array lookup. Copy an object property into a variable if it is going to be accessed repeatedly. Do not use the "with" statement, incidentally. It can slow down local variable access by introducing another object into the scope chain.
Variables defined in local scope will be accessed far more quickly than those in global, as the Javascript engine first looks through all of the variables locally, then checks all of the variables in global scope. Scopes can nest as well, so the farther up the nesting chain the variable resides the longer it will take to find. That's why it's best to cache something like "document" in a local variable if it is going to be accessed more than once.
Both are the same speed. Also, if you are concerned with the level of speed in accessing a field attached to a reference, I think you might be going down the wrong path to tuning your code.
I would venture to guess that data.property is ever-so-slightly faster, but it may be difficult to measure. Indeed, JSPerf shows no distinction
The best way of accessing object properties has generally nothing to do with speed. Dot operator is used for syntactic sugar (I.E. this.hasElements() is easier to read, write and process in your brain than this["hasElements"]()) whenever possible and the brackets are used when the key name is a variable or has illegal characters.
Primitive values are stored in a stack in javascript but objects are stored in a heap. I understand why to store primitives in stack but any reason why objects are stored in heaps?
Actually, in JavaScript even primitives are stored in the heap rather than on a stack (see note below the break below, though). When control enters a function, an execution context (an object) for that call to the function is created, which has a variable object. All vars and arguments to the function (plus a couple of other things) are properties of that anonymous variable object, exactly like other properties of named objects. A call stack is used, but the spec doesn't require the stack be used for "local" variable storage, and JavaScript's closures would make using a stack a'la C, C++, etc. for that impractical. Details in the spec.
Instead, a chain (linked list) is used. When you refer to an unqualified symbol, the interpreter checks the variable object for the current execution context to see if it has a property for that name. If so, it gets used; if not, the next variable object in the scope chain is checked (note that this is in the lexical order, not the call order like a call stack), and so on until the global execution context is reached (the global execution context has a variable object just like any other execution context does). The variable object for the global EC is the only one we can directly access in code: this points to it in global scope code (and in any function called without this being explicitly set). (On browsers, we have another way of accessing it directly: The global variable object has a property called window that it uses to point to itself.)
Re your question of why objects are stored in the heap: Because they can be created and released independently of one another. C, C++, and others that use a stack for local variables can do so because variables can (and should) be destroyed when the function returns. A stack is a nice efficient way to do that. But objects aren't created an destroyed in that straightforward a way; three objects created at the same time can have radically different lifecycles, so a stack doesn't make sense for them. And since JavaScript's locals are stored on objects and those objects have a lifecycle that's (potentially) unrelated to the function returning...well, you get the idea. :-) In JavaScript, the stack is pretty much just for return addresses.
However, it's worth noting that just because things are as described above conceptually, that doesn't mean that an engine has to do it that way under the hood. As long as it works externally as described in the spec, implementations (engines) are free to do what they like. I understand that V8 (Google's JavaScript engine, used in Chrome and elsewhere) does some very clever things, like for instance using the stack for local variables (and even local object allocations within the function) and then only copying those out into the heap if necessary (e.g., because the execution context or individual objects on it survive the call). You can see how in the majority of cases, this would minimize heap fragmentation and reclaim memory used for temporaries more aggressively and efficiently than relying on GC, because the execution context associated with most function calls doesn't need to survive the call. Let's look at an example:
function foo() {
var n;
n = someFunctionCall();
return n * 2;
}
function bar() {
var n;
n = someFunction();
setCallback(function() {
if (n === 2) {
doThis();
}
else {
doThat();
}
});
}
In the above, an engine like V8 that aggressively optimizes can detect that the conceptual execution context for a call to foo never needs to survive when foo returns. So V8 would be free to allocate that context on the stack, and use a stack-based mechanism for cleanup.
In contrast, the execution context created for a call to bar has to stick around after bar returns, because there's a closure (the anonymous function we passed into setCallback) relying on it. So when compiling bar (because V8 compiles to machine code on-the-fly), V8 may well use a different strategy, actually allocating the context object in the heap.
(If either of the above had used eval in any way, by the way, it's likely V8 and other engines don't even attempt any form of optimization, because eval introduces too many optimization failure modes. Yet another reason not to use eval if you don't have to, and you almost never have to.)
But these are implementation details. Conceptually, things are as described above the break.
The size of objects can grow dynamically. Therefore, you would need to adjust their memory requirements. That is why, they are stored in heap.
Both primitive values and objects are always stored in some other object - they are properties of some object.
There is not one primitive value / object that is not a property of another object. (The only exception here is the global object).