does V8 uses stack and heap like the JVM?
if so does it put primitives on the stack and objects on the heap?
In V8 null, undefined, true and false internally are heap allocated objects. If you are comming from Java you can say that true and false in V8 are more like Boolean.TRUE and Boolean.FALSE in Java.
There is an important difference between real local variables and variables that are captured by closures or shadowed by eval/with. Captures variables are stored in a special heap allocated structure called Context and are accessed indirectly. For more details about real vs. context allocates variables see my answer to a different question
V8 has two compilers: non-optimizing (aka full) and optimizing one:
Non-optimizing compiler can't store floating point numbers and integers beyond 31-bit (32-bit on x64) on the stack it always boxes them into HeapNumbers. It does not try to do register allocation and stores real local variables on the stack.
Optimizing compiler is much smarter. It does register allocation (linear scan) and can keep full 32-bit integers and floating point numbers on the stack and in the registers (including XMM registers).
Speaking of JVM: it can perform so called stack allocation and allocate a non-escaping object on the stack instead of the heap. A more generic optimization (scalar replacement) can sometimes completely eliminate allocation of non-escaping object and explode it into separate fields.
Yes, V8 uses a heap similar to JVM and most other languages. This, however, means that local variables (as a general rule) are put on the stack and objects in the heap. This may for instance not hold if a function closes over these values.
As in the JVM, primitives can only be stored on the stack if they are stored in a local variable.
As a user it is not something you would normally need to worry about.
In the most general terms, Yes V8 uses a heap and stack for functioning wherein general local variables are stored in the stack while the objects that need to be maintained are stored in the heap.
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 have looked all over the internet and I can't seem to find an answer to this question.
I read that the stack is used to store primitives and heap is for objects.
I also read that the stack's size is fixed and once allocated it does not change, hence why it's used for primitives, because JS knows the size of each variable before runtime.
I also know that primitives are immutable, so if we try to reassign a variable, it will not change the value at its memory address but will rather allocate new space in memory, store the new value and assign its address to the variable.
If the above is correct, then what happens when I do this?
let string = "Hello World"; // Memory allocated for "Hello World"
string = string.ToUpperCase(); // New memory allocated for "HELLO WORLD"
Where does the new memory for HELLO WORLD get allocated? Is it in the stack because it's a primitive? Or is it in the heap because JS does not know its value until it runs the code?
If it's in the stack, what happens to the old "Hello World" then? Since only the heap is garbage collected does that mean that the old, unused, string will stay there until the program finishes running?
What happens if I do
string = string.repeat(10000000000)
If the stack can't grow, does it mean that at some point I can stack overflow because a variable is too large?
Thank you.
The answer may vary by engine, and it really doesn't matter to your code. Worry about running out of stack if/when you run out of stack. JavaScript's specification doesn't require implementations to do one thing or the other. It describes behavior, not the implementation of that behavior.
But speaking practically: It seems unlikely that a JavaScript engine would try to put a massive string on the stack. More likely, it would put it in the heap. That doesn't mean it can't put other strings on the stack. Maybe it decides based on size. Maybe it decides based on lifetime — perhaps it'll put a small string used only locally in a function on the stack, but put a massive one, or one retained globally, on the heap.
The point is: Modern JavaScript engines are complicated and highly, highly optimized. They're unlikely to take such a simplistic view as "primitives go on the stack and objects go on the heap."
I read that the stack is used to store primitives and heap is for objects.
Not necessarily. Objects can be allocated on the stack as well, and have been by at least some JavaScript engines at various points in history. If an object won't survive the end of the function call, and isn't massive, putting it on the stack makes reclaiming it when the function returns dead easy.
I also know that primitives are immutable, so if we try to reassign a variable, it will not change the value at its memory address but will rather allocate new space in memory, store the new value and assign its address to the variable.
Without getting too deep into theory, again this could well be implementation-specific. Consider a = 1. We have no way of telling whether that puts the value 1 in the memory associated with a, or puts a reference to an immutable singleton representing 1 in a. The former seems more a lot more likely than the latter (for numbers; strings are another matter), but we don't know and can't know (in the general case; we can for a specific version of a specific engine), because it makes no difference to our code and the spec doesn't require one behavior or the other.
Are ES2015 typed arrays allocated inside the runtime heap?
Or is it left to implementation?
If I understand correctly, Node.js Buffer instances are allocated outside the runtime heap (source: "A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap").
ECMAScript 6 does not specify any mechanism of memory allocation.
Engines are free to implement what they want. I'd expect them to be allocated on the heap as it is the default for all objects, but they might as well go on the stack frame for optimisation purposes or in a dedicated "heap" segment with special garbage collection semantics.
I have few basic questions about dynamic object creation using Javascript.
I understand that browser takes care of allocating memory space for any 'new' keyword found in the JS. If my understanding is correct, then i have following queries one by one.
Query #1 : Please refer the comments given below for the two lines inside 'sample' function. That is my first query.
function sample() {
var a = 5; // is the memory allocated for variable 'a' in stack ?
var b = new obj1(); // The object instance created for 'obj1' gets allocated in heap?
}
var obj1 = function() {
this.strDate = "";
}
Query #2: Once the execution scope is out of function sample(), will the browser engine free the memory allocated for both the variables. I have read about GC's reference algorithm & mark and sweep algorithm
and recommendations to assign null to variables once not in use, yet could not get a clear cut idea on the standards to be followed as we would do in C++. If variable a is there in stack, then I need not worry
and if obj1 instance is no longer accessible or say unmarked or no further reference to it, will it also be cleared by GC ?.
Query #3: Do browsers differ in allocating and freeing memory for the instances created using 'new' operator. ( I had seen only about heap profilers in chrome and rather few more terms related to it, but I have also come across 'out of stack space' error. Does that mean all browsers would universally use both stack and heap ?
Please help me out here ;)
As a programmer, in JavaScript you do not have control over stack or heap allocation. You create objects or primitives that are located somewhere in the memory. Internally JS engines (such as V8 or Spidermonkey) perform all kinds of optimizations. Generally you can think of everything as if it's stored on heap.
To get started you need to know that GC frees the memory from the objects that are not referenced. While you hold a reference to an object somewhere in your code, it will not be destroyed.
Browsers (JS engines) do not leak memory allocation abstraction to you. The error you're referring to is probably call stack exceeded that happens when too many functions are called (mostly due to recursion).
In other words, what options do I have to allocate memory in JavaScript?
I know you can allocate memory either globally, or inside function scope. Can I allocate memory dynamically? What does the new operator really mean?
Edit: here's a specific example. How would you implement reading an integer value from the user - n, and then read n integers into an array?
you can't allocate memory. you can create objects. that's what new does.
now, javascript is a queer creature: functions are also objects in javascript. So this mean that you can instantiate prettymuch everything using new.
So, the new operator means that a new object is being created.
Javascript also garbage-collects these variables, just like it happens in java. So if you know java, it should be easy for you to draw parallels.
cheers,
jrh
PS: when you allocate objects, you really are allocating memory. Only, you are not doing that explicitly. You can allocate an array, and make it behave like a memory buffer, but that will degrade javascript performance drastically: javascript arrays are not in-memory buffers, they are also objects (like everything else).
JavaScript has garbage collection and handles this for you.
However, you can help it by using the delete operator where appropriate.
From the Apple JavaScript Coding Guidelines:
Just as you used the new operator to
create an object, you should delete
objects when you are finished with
them, like this:
delete myObjectVariable;
The JavaScript runtime automatically
garbage collects objects when their
value is set to null. However, setting
an object to null doesn’t remove the
variable that references the object
from memory. Using delete ensures that
this memory is reclaimed in addition
to the memory used by the object
itself. (It is also easier to see
places where your allocations and
deallocations are unbalanced if you
explicitly call delete.)
Steve
Hmmm sounds to me like you are coming from the memory focused language and trying to shoe horn that logic into JS. Yes JS uses memory (of course), but we have garbage collection to take care of cleaning it all up.
If you are after specifics about the guts of memory allocation then you will have to hunt around for that. But as a rule thumb, when you use var, new or declaring a new function (or closure) you are gobbling up memory. You can get vars to null to flag them for garbage collection and you can use the delete keyword too although few do either of these unless they work Server-side (like myself with ASP JScript) where its important.
Javascript is really, really friendly — really, too friendly by half!
If you have an array of 3 elements, and you want to add a fourth, you can just act as if that array location already exists:
var arr = ['zero', 'one', 'two'];
// Now you have arr[0], arr[1] and arr[2].
// arr.length is equal to 3.
.
// to add arr[8]:
arr[8] = 'eight';
// Now you have arr[0] through arr[8]. arr.length is equal to 9.
// and arr[3] through arr[7] exist, and
// are initialized to undefined. (If I remember right.)
So being really specific with memory allocation is unnecessary when adding elelments.
No, you don’t need to and can’t allocate memory. The JavaScript interpreter does that automatically.
To answer the title of the question, if you are to trust in MDN, most JavaScript implementations have a heap:
Heap
Objects are allocated in a heap which is just a name to denote a large
mostly unstructured region of memory.
Several Runtimes Communicating Together
A web worker or a cross-origin iframe has its own stack, heap, and
message queue. Two distinct runtimes can only communicate through
sending messages via the postMessage method. This method adds a
message to the other runtime if the latter listens to message events.
For a deeper dive into memory management, there is also an article here although much of this is implementation specific.
You do not need to manually manage memory in Javascript. Both heap and stacks are used under the hood to manage memory and it depends on the implementation. Usually, local variables are on the stack and objects are on the heap.