2

I'm new to development, just need to know in terms of memory does it matter using a value without assigning in to a variable

Example 1:

var sendResponse = {
    "a": 1,
    "b": 2
};
res.send(sendResponse);

OR

res.send({
    "a": 1,
    "b": 2
});

Example 2:

var valueOne = "hi";
var valueTwo = "hithere";

    if (someVariable  == valueOne  || someVariable == valueTwo) {
        //
    }

    OR

    if (someVariable  == "hithere" || someVariable == "hi") {
        //
    }

Example 3:

var concatOne = "hi";
    var concatTwo = "hithere";

    var concatString = concatOne + concatTwo;

    OR

    var concatString = "hi" + "hithere";
  • There is no functional difference. Those are simply different code styles, have different readability, etc. – luk2302 Jul 17 '21 at 12:31
  • Each reference costs at least 8 bytes if it can't be optimized. –  Jul 17 '21 at 12:33
  • @luk2302 thanks for responding, one of my senior told me, assigning all hard coded values to variable is good practice because some hard coded values sometimes are not reachable by GC , is it true ? – Nikit Panchal Jul 17 '21 at 12:34
  • @jabaa JavaScript is not C. There is no defined "size" of a reference in JavaScript. – Dai Jul 17 '21 at 12:34
  • @Dai Yes, therefore I wrote _"at least"_. A reference has a minimum size but can be larger. They have at least pointer size –  Jul 17 '21 at 12:35
  • @NikitPanchal If by "hardcoded" you mean _literals_, then it doesn't make a difference because literals are interned, and if they're used as parameters then they'll have a reference to them regardless. – Dai Jul 17 '21 at 12:35
  • @jabaa But my point is that there is no "minimum size" - there is nothing that requires an reference in JS to be "8 bytes". – Dai Jul 17 '21 at 12:36
  • @Dai They have at least pointer size and I neglect systems with 32 bit pointers today for JavaScript development. –  Jul 17 '21 at 12:36
  • @jabaa No, they don't. I used to work on Chakra at Microsoft and I can tell you _first hand_ that there are plenty of cases where objects and strings can be passed-around "by reference" without using pointers or pointer-sized references or handles. One example is small-string-optimization, which is commonplace in C++ too: https://stackoverflow.com/questions/21694302/what-are-the-mechanics-of-short-string-optimization-in-libc – Dai Jul 17 '21 at 12:37
  • @Dai Is https://stackoverflow.com/questions/32538685/size-of-an-object-reference-in-javascript-v8 wrong in that case? This question is about Node.js –  Jul 17 '21 at 12:38
  • @jabaa That posting is not authoritative. The answer gave no source or citation. Going by my own experiences with Chakra I would be very surprised if that actually is true. – Dai Jul 17 '21 at 12:39
  • @Dai I also wrote _"if it can't be optimized"_ but I would be very surprised about a reference size > 0 and < 8 bytes. It's either completely optimized or it's at least a pointer. –  Jul 17 '21 at 12:41
  • @jabaa Then your answer isn't particularly useful then because you're basically saying "if it's optimized it's less than 8 bytes, if it's not optimized it's at least 8 bytes". - also, what _exactly_ do you mean by "optimized"? – Dai Jul 17 '21 at 12:43
  • @Dai I'm practically saying if it's optimized it's 0 size and if it's not optimized it's at least 8 byte. I don't know the optimizer rules for JavaScript and but I assume in most cases it's not possible to optimize. –  Jul 17 '21 at 12:46
  • 3
    Just to make one thing clear. It started as a half joke and ended in a discussion. We're talking about microoptimizations. Don't do that as long as it's not your bottleneck. Write readable and maintainable code. Create variables and waste a little memory to avoid bugs. A bug in production because of a microoptimization is much more expensive. Literals instead of variables could cause code duplication. –  Jul 17 '21 at 12:47
  • 1
    @jabaa Agreed. These are the kinds of "a little knowledge is dangerous"-type questions... – Dai Jul 17 '21 at 12:54

2 Answers2

1

Short answer:

It doesn't matter.

Cop-out answer:

What you're asking is basically the JavaScript equivalent of "How much memory does an rvalue take?" in C++, which has a good answer here.

Longer answer:

If you absolutely care about memory usage and performance then you shouldn't be using JavaScript in the first place (yes, modern JS JITs are very fast and are fast-approaching traditional AOT-compiled languages like C++, but there's still a huge memory tradeoff and first-run performance-hit for the JIT).

Secondarily, the kind of optimization you're referring to is a microoptimization - even if there are savings to be made by putting string-literals directly as arguments it would maybe save you maybe a handful of bytes for the entire script execution, compare that to the tens-to-hundreds of megabytes of memory that V8 will happily use (and that's still a fraction of the presumably dozens of gigabytes of RAM that your computer has).


(The technical details below are generalities and are not specific to V8 - which I'm not intimately familiar with, though I do have first-hand experience with the internals of Chakra from my time at Microsoft).

Some things to consider:

  • Most importantly: the JavaScript specification does not dictate how a JS engine is implemented. Someone could build a horribly inefficient engine that uses a gigabyte of internal memory for each variable and still comply with the spec. To give a perfect answer to your question would require a through and in-depth knowledge of V8's internals - and such knowledge would be outdated and obsolete within a few years anyway given how fast the JS ecosystem changes.

  • Most modern JavaScript engines (including V8) generally have 3 modes of operation:

    1. Parsing.
    2. Interpreted mode.
    3. JIT mode.
  • Before a script can be executed it needs to be parsed: and when a script is being parsed any string-literals will be interned and kept in read-only memory (and so the string values consume a fixed, known, quantity of memory), which means that those values will never be destroyed by the GC.

    • Side-note: some systems (like Win32 and Prolog) refer to these as "string atoms" or "atomic strings" instead of "interned strings", with subtly different semantics.
    • (I accept that string-literals in dynamically evaluated scripts (namely in eval()) may be reclaimed - however I don't believe (but I could easily be wrong!) that any JS engines' GC today will free string literals that have no references pointing at them.
  • After a string literal has been interned it's possible for a JS engine's user-script variables to use some internal tagged reference type to succinctly refer to the string without needing to use a full 8-byte internal pointer (similar to, but not exactly nor necessarily a tagged pointer), there is also the possibility for small-string-optimization to be used (where a local copy of the entire string, if it's small enough, is used instead of a pointer or reference to the string - this is fairly commonplace in C++ to avoid the runtime costs of multiple indirection).

  • Don't conflate memory used by a reference or local to the memory used by the value.

    • Memory usage by references/locals is difficult to identify because any fairly decent JIT will perform a lot of operations entirely within CPU registers and other non-memory addresses - as well as predetermining many operations as though they were like C++ constexpr - so if a variable is elided away does it still use any memory? does it use "zero" bytes? that's more a philosophical question, imo.
  • (there's loads more I could write on this subject but it's 7am now and I'm off...)

Dai
  • 141,631
  • 28
  • 261
  • 374
  • thanks for your answer If you could take few minutes to check the screen shots of my heap stack i have uploaded 1. In this screen shot contains code snippet in which i'm sending response data and total count of patient [link](https://ibb.co/Jxv1YZd) 2.In this screen shot that concated string 'patients found' shows up in heap stack as memory leak, it have allocated 32bytes and not freed [link](https://ibb.co/RStpLst) 3.In this screen there are many more such literal strings showing up as mem leak. [link](https://ibb.co/Chz1rnz) Could you help me understand why its happening ? – Nikit Panchal Jul 17 '21 at 14:11
  • @NikitPanchal Those are **runtime strings**, not string literals. That's very different to your original question which was only concerned with aliasing values through variables and string interning. – Dai Jul 17 '21 at 14:12
-2

Yes it does, Because when you declare a variable in JS we are not specifying the size that variable going to hold so it allocates a minimal space for every variable we create , as well as the names we give to every variable will also take some space. So in case of dynamic allocation its okay do that , But the second method in every example is the preferred one.

var concatOne = "hi";
var concatTwo = "hithere";

var concatString = concatOne + concatTwo;

here the "var" keywords does not know which data type your going to use so it will be allocated the most heights data type size like big int , and also the two variable names also holds some space.

But the another method is priffered to be a good practice with optimized memory use as well as shorter code size, which can improve your code working performance the compilation and run time will be considerably lower

  var concatString = "hi" + "hithere";
  • _"here the "var" keywords does not know which data type your going to use so it will be allocated the most heights data type size like big int"_ Do you have a reference for this? I don't believe it. Big int can store arbitrarily large integers. It would need to allocate infinite memory for each variable. –  Jul 17 '21 at 12:52
  • 1
    "Because when you declare a variable in JS we are not specifying the size that variable going to hold so it allocates a minimal space for every variable we create" - this is not universally true, and is demonstrably false in the case of a JITt'd method's _locals_ for simple scalars, which are not "allocated" in the sense as though memory is being claimed on the heap: because the JIT will have been satisfied that they can be _autos_ and exist (over-simplification) on the stack. – Dai Jul 17 '21 at 12:52