Hacker News new | past | comments | ask | show | jobs | submit login

V8 dev here.

Yes, please avoid leaking memory -- but the intro to this article is incorrect in almost all major points:

> In JavaScript, primitives are assigned/passed by value and not by reference. If you assign a primitive type's value to another variable, the value is copied.

No, primitives are immutable but still passed by reference (that reference is passed by value, which is why assigning to the reference won't change them -- the same is true for objects). Can you imagine if we'd copied strings every time they were passed into a function?

> This also determines how they are stored in memory — primitive values are stored on the stack while objects are stored on the heap, with a reference to their location stored on the stack.

Also no, all primitives except small integers ("Smis") are stored in the heap.

> One important thing to note about variables stored in the stack is that their sizes must be known at compile time. This allows a program to allocate the right amount of memory in the stack. Because the JavaScript engine allocates a fixed amount of memory for primitive values, there is a limit to how large they can be.

Again, no, with strings as the obvious counter example. There's a limit to how large values in general can be, but it's around indexable size and pointer width, not a fixed amount of memory for primitives.

> Memory stored in the heap will live on unless it is explicitly deleted or deallocated.

Is the author confusing the malloc heap with the (garbage collected) JS heap? Sure, V8 has to manage the pages it allocates, but JS authors certainly don't

> To allocate memory in the heap, a program must first scan the heap to find a contiguous memory block large enough to hold the data.

As a sibling comment points out, there are optimisations here with linear allocation buffers that permit bump allocation. Also, don't forget the semi space for young objects, since the GC is generational.




> No, primitives are immutable but still passed by reference

For immutable values the pass-by-reference vs pass-by-value distinction isn't really important. Unless the language provides some way to get the identity of the object there isn't a way to tell a difference.

> Can you imagine if we'd copied strings every time they were passed into a function?

IIUC most Javascript interpreters optimize copying strings anyways, so this wouldn't be a big deal. For example even though `s.slice(1)` is a "copy" most engines (I believe V8 included) will use the same backing string for both. So the difference would be a pointer on the stack vs a pointer+length on the stack and copying an extra word is not a huge difference.

But maybe this is just being nitpicky, since the article is focused on performance the lower level details do mater not the semantics. However for strings I don't think the difference between their model and reality is very significant.


You're talking about semantics and you're totally right, there's plenty of cases in the implementation where things are not copied when they should be (string slices) or copied when they shouldn't be (boxed double writes into mutable double boxes). As you say though, the semantics are kind of irrelevant when you're talking about actual memory behaviour of allocations.

There's actually lots of really interesting consequences of the current implementation, and the various tricks it does around what's observable and what's fast, it's just not what's described here.


> For example even though `s.slice(1)` is a "copy" most engines (I believe V8 included) will use the same backing string for both.

That’s not a copy, it skips the first character!


It's semantically a copy of most of the string.


Nothing against the author, but damn is this a good example of why you can't just trust every piece of technical writing you see.


Maybe strings are not considered primitives by the author. They do give a list of "Data types stored in the stack" which I understood to be the "primitives" in what follows.


From the article, "Data types stored in the stack include: [...] string"


Ouch. Yeah that's wrong.


only SMIs are passed by value (because they are actually encoded in the reference data type)

It might be a bit outdated but here's more https://github.com/thlorenz/v8-perf

Also the https://v8.dev/ blog is awesome.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: