Uninitialized variable memory allocation - javascript

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.

Related

How v8 handle stack allocated variable in closure?

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.

Does a Javascript closure retain the entire parent lexical environment or only the subset of values the closure references? [duplicate]

This question already has answers here:
About closure, LexicalEnvironment and GC
(3 answers)
Closed 3 years ago.
Consider the following example:
function makeFunction() {
let x = 3;
let s = "giant string, 100 MB in size";
return () => { console.log(x); };
}
// Are both x and s held in memory here
// or only x, because only x was referred to by the closure returned
// from makeFunction?
let made = makeFunction();
// Suppose there are no further usages of makeFunction after this point
// Let's assume there's a thorough GC run here
// Is s from makeFunction still around here, even though made doesn't use it?
made();
So if I close around just one variable from a parent lexical environment, is that variable kept around or is every sibling variable in its lexical environment also kept around?
Also, what if makeFunction was itself nested inside another outer function, would that outer lexical environment be retained even though neither makeFunction nor makeFunction's return value referred to anything in that outer lexical environment?
I'm asking for performance reasons - do closures keep a bunch of stuff around or only what they directly refer to? This impacts memory usage and also resource usage (e.g. open connections, handles, etc.).
This would be mostly in a NodeJS context, but could also apply in the browser.
V8 developer here. This is a bit complicated ;-)
The short answer is: closures only keep around what they need.
So in your example, after makeFunction has run, the string referred to by s will be eligible for garbage collection. Due to how garbage collection works, it's impossible to predict when exactly it'll be freed; "at the next garbage collection cycle". Whether makeFunction runs again doesn't matter; if it does run again, a new string will be allocated (assuming it was dynamically computed; if it's a literal in the source then it's cached). Whether made has already run or will run again doesn't matter either; what matters is that you have a variable referring to it so you could run it (again). Engines generally can't predict which functions will or won't be executed in the future.
The longer answer is that there are some footnotes. For one thing, as comments already pointed out, if your closure uses eval, then everything has to be kept around, because whatever source snippet is eval'ed could refer to any variable. (What one comment mentioned about global variables that could be referring to eval is not true though; there is a semantic difference for "global eval", a.k.a. "indirect eval": it cannot see local variables. Which is usually considered an advantage for both performance and debuggability -- but even better is to not use eval at all.)
The other footnote is that somewhat unfortunately, the tracking is not as fine-grained as it could be: each closure will keep around what any closure needs. We have tried fixing this, but as it turns out finer-grained tracking causes more memory consumption (for metadata) and CPU consumption (for doing the work) and is therefore usually not worth it for real code (although it can have massive impact on artificial tests stressing precisely this scenario). To give an example:
function makeFunction() {
let x = 3;
let s = "giant string, 100 MB in size";
let short_lived = function() { console.log(s.length); }
// short_lived(); // Call this or don't, doesn't matter.
return function long_lived() { console.log(x); };
}
let long_lived = makeFunction();
With this modified example, even though long_lived only uses x, short_lived does use s (even if it's never called!), and there is only one bucket for "local variables from makeFunction that are needed by some closure", so that bucket keeps both x and s alive. But as I said earlier: real code rarely runs into this issue, so this is usually not something you have to worry about.
Side note:
and also resource usage (e.g. open connections, handles, etc.)
As a very general statement (i.e., in any language or runtime environment, regardless of closures or whatnot), it's usually advisable not to rely on garbage collection for resource management. I recommend to free your resources manually and explicitly as soon as it is appropriate to free them.

Do variables declared inside callback functions remain in memory or are they destroyed upon end of callback execution?

I have this code snippet; It basically connects to mongo database and goes through documents. On each iteration it searches for messages array of objects. It creates variable of messages, and then loops through it. Does declared variable (var msg) inside callback function remain in memory or is it destroyed upon end of callback function execution? Would there be any difference if var msg was actually declared as let msg? Is there a way to discard whole scope from the memory?
MongoClient.connect(mongoUrl, (err, db) => {
assert.equal(null,err);
var collection_data = db.collection('threadContents').find();
collection_data.on('data', (doc) => {
var msg = doc.messages;
for (var variable in msg) {
console.log(msg);
}//forin(msg)
});//collection_data.on
});//mongo.connect
In theory - yes.
In practice - it's not that simple...
In your example, var msg does not "leak" outside of it's original scope, so it will most likely get destroyed when callback finishes it's job.
One thing to note - the destruction of this object doesn't have to happen immediately - JS Engines are mostly Garbage Collected, so this piece of memory can stay on the stack for some time, but it won't be reachable anymore.
If you would declare this variable in outer scope, it could possibly stay in the memory if that scope stayed in memory (so, other pieces of code could access that variable). You can read about this behavior in Closures section at MDN.
Another thing to note is usage of console.log. In general, non-primitive values (like Objects or Arrays, which actually are "special" objects), will be accessible by reference, not by value. Therefore, if your var msg is a non-primitive, it will most likely persist in the memory until you clear your console. Primitive values would be copied, so strictly speaking they would still persist in the memory, but probably in another place in the memory (although JIT engines could probably try to optimize that and don't copy the memory if it's not necessary).
Node.js (and all javascript engines) rely on tracing garbage collection, which means that allocated memory is deallocated in a non-deterministic way, i.e. you cannot predict exactly when it will happen. This usually does not affect you, but uif you really want some chunk of memory or some other resource to be deallocated in a predictable way, you have to use some ad-hoc technique.
In your specific example 'msg' will be deleted, but don't expect it to be deleted straight away.

JavaScript- properties and variables

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.

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