As far as I know, JavaScript code goes through two phases: compilation phase and execution phase, when a JavaScript engine like V8 runs our code.
I wonder when the heap memory is actually allocated for a function.
More specifically, if I declare function and not call it in our code, does the JavaScript engine such as V8 still allocate memory for the function in the compilation phase?
Thank you
It's a bit more complicated than just two phases. Engines typically try to save memory when they can, but nothing is entirely free. It's safe to assume that a function that's never called consumes less memory than one that is called, but not zero.
In V8 in particular, (most) code is at first "pre-parsed". The preparser leaves behind some metadata about functions it has seen; mostly where in the source they start/end and some information about which variables from their outer context, if any, they'll need.
When program execution reaches a point where a function becomes available to JavaScript (as a variable), an actual object is created for it. This function object does not contain code or bytecode yet.
When a function is called, it is just-in-time compiled to bytecode. From this point on, memory is consumed for the bytecode.
If V8 notices that a lot of time is spent in the function, it may decide to generate optimized code for it. Optimized code is stored in addition to the bytecode, so the function's memory consumption grows again. Some functions never reach this point (e.g. when they're only called a few times).
Of course, when a function is executed, it can create other objects. (That's probably not what you're asking; just mentioning it for completeness.)
Related
I know that JavaScript is a dynamic type language and executes programs divided by evaluation and execution processes. And JavaScript registers variables in the Lexical environment of the execution context during the evaluation process, and allocates the actual value while executing the allocation statement during the execution process.
Here I was wondering how JavaScript allocates memory for each variable during the evaluation process.
Because it's before JavaScript evaluate the type, is JavaScript allocating it to a certain byte size and keeping each of them away?
I could find many articles about JavaScript's memory management, but I couldn't figure out how the allocation occurred in the beginning.
Is there any way I can know this?
AFAIK it will use the stack for everything that has a known size and for the rest it uses the heap.
I found this article useful.
https://felixgerschau.com/javascript-memory-management/#the-memory-heap-and-stack
I was learning the inner workings of V8 and found out that there is JIT compiler which, on the fly, optimizes the hot functions with inline caching technique. I have only two questions, firstly, is function considered as hot function as long as it is executed repeatedly one after another several times? Secondly, after what exact number of repeated execution function gets hot in V8?
V8 developer here. Function "hotness" is not simply determined by the number of calls to it. Instead, V8 tries to predict how useful it would be to optimize a given function by estimating the amount of time spent executing the unoptimized version of that function. The exact heuristics of how this works, which other factors are taken into account (e.g. completeness/stability of type feedback), and the threshold when optimized compilation is triggered can and do change over time.
The reason is that optimized compilation is fairly expensive, so you'd only want to do it when it's likely to pay off. ("likely" because it depends in particular on how much work the function will do in the future, and predicting the future accurately is of course impossible, so there's always some amount of guesswork and heuristics involved.)
how does the jit compiler work in JAVASCRIPT ???
when we only have a 1 compilation phase which declares all of our variables and functions (during the creation of the glbal execution context ?o
...when we only have a 1 compilation phase which declares all of our variables and functions...
That's where you're going wrong. :-) Modern JavaScript engines don't have a single compilation phase. Instead, they do an initial pass through the code using something really fast, and then for code that gets reused enough to make it worthwhile, they apply an optimizer to rewrite the code in place with faster code.
In Chrome's V8, the first phase used to be a compiler (called Full-codegen) and the second phase (when needed) was an optimizing compiler called Crankshaft, but they've switched to an interpreter called Ignition for the first phase that parses the code, generates bytecode, and executes that, and then for code that makes it worthwhile, they apply an optimizing compiler called TurboFan to the bytecode. (See that blog post for the details.) This was originally to minimize the memory impact of one-off setup code, but it turned out that generating bytecode was faster than generating machine code and startup performance was actually improved as well.
In JavaScript: Understanding the Weird Parts the instructor explains that memory for variables is set up during a so-called creation phase (and that undefined is assigned); then the execution phase happens. But why is this useful when we don't know what value(s) the variable will later point to?
Clearly variables can point to many different things -from e.g. a short string all the way to a deeply nested object structure -and I assume that they can vary wildly in the amount of memory they need.
If line-by-line execution -including variable assignment -happens only in the later, execution phase, how can the initial creation phase know how to set up memory? Or, is memory set aside only for the name in each variable name/value pair, with memory for the value being managed differently?
The instructor is referring to Google Chrome's V8 engine (as is evidenced by his use of it in the video).
The V8 engine uses several optimization approaches in order to facilitate memory management. At first, it will compile the JavaScript code and during compilation it will determine how many variables (hidden classes, more later) it needs to create. These will determine the amount of memory originally allocated.
V8 compiles JavaScript source code directly into machine code when it is first executed. There are no intermediate byte codes, no interpreter. Property access is handled by inline cache code that may be patched with other machine instructions as V8 executes. 1
The first set is created by navigating the JavaScript code to determine how many different object "shapes" there are. Anything without a prototype is considered to be a "Transitioning object shape"
The main way objects are encoded is by separating the hidden class (description) from the object (content). When new objects are instantiated, they are created using the same initial hidden class as previous objects from the same constructor. As properties are added, objects transition from hidden class to hidden class, typically following previous transitions in the so-called “transition tree”. 2
Conversely, if the object does have a prototype then it will have its particular shape tracked separately.
Prototypes have 2 main phases: setup and use. Prototypes in the setup phase are encoded as dictionary objects. Any direct access to the prototype, or access through a prototype chain, will transition it to use state, making sure that all such accesses from now on are fast. 2
The compiler will essentially read all possible variables as being one of these two possible shapes and then allocate the amount of memory necessary to facilitate instantiating those shapes.
Once the first set of shapes is setup, V8 will then take advantage of what they call "fast property access" in order to build on the first set of variables (hidden classes) that were setup during the build.
To reduce the time required to access JavaScript properties V8 dynamically creates hidden classes behind the scenes 3
There are two advantages to using hidden classes: property access does not require a dictionary lookup, and they enable V8 to use the classic class-based optimization, inline caching 3
As a result, not all memory use is known during compilation, only how much to allocate for the core set of hidden classes. This allocation will grow as the code is executed, from things like assignment, inline cache misses, and conversion into dictionary mode (which happens when too many properties are assigned to an object, and several other nuanced factors).
1. Dynamic machine code generation, https://github.com/v8/v8/wiki/Design%20Elements#dynamic-machine-code-generation
2. Setting up prototypes in V8, https://medium.com/#tverwaes/setting-up-prototypes-in-v8-ec9c9491dfe2
3. Fast Property Access, https://github.com/v8/v8/wiki/Design%20Elements#fast-property-access
Javascript is a bit of a problem you know at least in my opinion
in Javascript there are specifications of the language made by ecmascript
and there are implementation made by developers
you have to understand that what is been taught about Javascript what's so called "under the hood" are the specifications of Javascript
you might have heard the terms Execution Context Lexical Environment.
They are only spec on how the language should work they give idea to the Developers how to build their JS engine in a way that it will behave like the spec.
An execution context is purely a specification mechanism and need not correspond to any particular artefact of an ECMAScript implementation. It is impossible for ECMAScript code to directly access or observe an execution context. ECMAScript
Every Javascript engine is implemented differently and they supposed to behave like the spec of ECMAScript
there is a concept that everytime when an execution context is created.
it has stages creation phase and execution phase.
everytime when creation phase begin it's allocating memory for the variables for that execution context.
in reality it doesn't work like that at all
there is no really a "Creation Phase" at least in V8 engine(Google Chrome JS Engine) in the way that you think.
i can give you a hint and tell you that eveytime when you call a function that
doesn't have another function inside it.
the variables inside that function are basically replacing some "block" in memory
i will give you a basic example let's say V8 engine uses some address in memory
let's say the address is 0x61FF1C
function setNum(){ var num = 5; }
everytime when i will call the setNum function the value for example of num will get stored at address 0x61FF1C EVERYTIME when i will call the function the value of num 5it will get stored at 0x61FF1C so it's overwriting the content that were before inside 0x61FF1C.
that's just how the v8 engine works in that scenario now the example i gave is just to get the idea i know it's sounds a little vague.
there is much more to the V8 engine which i'm not going to discuss because it's huge
by the way i'm not a V8 developer so i dont know everything about that engine
i'm not even close to that level but i know some things.
anyway i think that every JS Developer should think in the spec way but also remember that many engines behave like the spec but it doesn't mean that they work exactly like the spec
When any program executes, time of execution we call running time. During running time or processing time, processor process code and communicate with memory. Procesor takes code from memory, process it, result give back to memory, take other code. All the running time, some space in memory get grater; some space gets zero, some variables get the new value, some variables have been deleting, etc. Volume of working memory in running time is changing all the time.
In a Javascript program that runs within WSH and creates objects, let's say Scripting.FileSystemObject or any arbitrary COM object, do I need to set the variable to null when I'm finished with it? Eg, am I recommended to do this:
var fso = new ActiveXObject("Scripting.FileSystemObject");
var fileStream = fso.openTextFile(filename);
fso = null; // recommended? necessary?
... use fileStream here ...
fileStream.Close();
fileStream = null; // recommended? necessary?
Is the effect different than just letting the vars go out of scope?
Assigning null to an object variable will decrement the reference counter so that the memory management system can discard the resource - as soon as it feels like it. The reference counter will be decremented automagically when the variable goes out of scope. So doing it manually is a waste of time in almost all cases.
In theory a function using a big object A in its first and another big object B in its second part could be more memory efficient if A is set to null in the middle. But as this does not force the mms to destroy A, the statement could still be a waste.
You may get circular references if you do some fancy class design. Then breaking the circle by hand may be necessary - but perhaps avoiding such loops in the first place would be better.
There are rumours about ancient database access objects with bugs that could be avoided by zapping variables. I wouldn't base my programming rules on such voodoo.
(There are tons of VBscript code on the internet that is full of "Set X = Nothing"; when asked, the authors tend to talk about 'habit' and other languages (C, C++))
Building on what Ekkehard.Horner has said...
Scripts like VBScript, JScript, and ASP are executed within an environment that manages memory for you. As such, explicitly setting an object reference to Null or Empty, does not necessarily remove it from memory...at least not right away. (In practice it's often nearly instantaneous, but in actuality the task is added to a queue within the environment that is executed at some later point in time.) In this regard, it's really much less useful than you might think.
In compiled code, it's important to clean up memory before a program (or section of code in some cases) ends so that any allocated memory is returned to the system. This prevents all kinds of problems. Outside of slowly running code, this is most important when a program exits. In scripting environments like ASP or WSH, memory management takes care of this cleanup automatically when a script exits. So all object references are set to null for you even if you don't do it explicitly yourself which makes the whole mess unnecessary in this instance.
As far as memory concerns during script execution, if you are building arrays or dictionary objects large enough to cause problems, you've either gone way beyond the scope of scripting or you've taken the wrong approach in your code. In other words, this should never happen in VBScript. In fact, the environment imposes limits to the sizes of arrays and dictionary objects in order to prevent these problems in the first place.
If you have long running scripts which use objects at the top/start, which are unneeded during the main process, setting these objects to null may free up memory sooner and won't do any harm. As mentioned by other posters, there may be little practical benefit.