How do JS strings allocate memory?

As you probably know, strings live in a string constant pool and are referenced by variables on the stack or heap. If the value of the variable is a string literal, the variable on the stack refers directly to the string in the string constant pool; If it’s a String created by a new String, it creates a String on the heap that points to a String in the String constant pool, and a stack variable that points to a String in the heap.

Is that true?

Today we will use the Chrome Devtools Memory tool to prove:

The Memory tool proves how strings allocate Memory

We prepare a code like this:

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>

    <script>
        const arr = [];
        setTimeout(() = > {
            for(let  i = 0; i<10000; i++) { arr.push('guang'); }},3000);

        const arr2 = [];
        setTimeout(() = > {
            for(let  i = 0; i<10000; i++) { arr2.push(new String('guang')); }},5000);
    </script>
</body>
</html>
Copy the code

At 3s, create an arR array of 10000 elements, whose element is the string constant “guang”.

On 5s we create a 10000 element array arR2 with new String(“guang”).

In theory, elements in ARR are strings that refer directly to the String constant pool, and elements in ARR2 refer to strings on the heap, which in turn refer to strings in the String constant pool.

Let’s use the Memory tool to verify this.

Chrome Devtools provides Memory tools for analyzing objects in Memory:

There are three types of memory analysis tools:

  • Snapshot: Snapshot of heap memory at a point in time
  • TimeLine: Displays real-time memory allocation based on the TimeLine
  • Sampling: Collect memory allocation information

We want to see real-time distribution by TimeLine, so we use the second tool: TimeLine.

Load the page, click Record, and the memory allocation will be displayed on the right in real time:

We record 6s and hit stop.

You can see that there are two vertical lines, each representing two memory allocations.

Click on the first memory allocation to see details:

As you can see, both string and array objects are created at this point in time:

The memory address of the string “guang” is @169541.

Array elements also point to @169541

This verifies that the string constant pool exists and that string literals refer directly to strings in the constant pool.

Let’s look at the second memory allocation method (new String(“guang”)) :

As you can see, create a String, array variable (system is an internal object assigned by the JS engine, don’t care) :

The String object references the String “guang” in the String constant pool at @169541

The elements in the Array refer to the addresses of different strings:

This again verifies the existence of a String constant pool and that String objects are allocated memory on the heap and then refer to strings in the String constant pool.

String literals refer directly to the String address of the String constant pool. String objects are allocated space on the heap and then refer to the String address of the String constant pool.

We’ve only created the string “guang” once from beginning to end, so the benefits of the string constant pool are obvious.

In addition, we can conclude that creating a String is a lot more memory expensive, so we recommend using String literals:

From the figure, you can intuitively compare the difference of memory occupied by the two methods.

The test code is uploaded to github: github.com/QuarkGluonP…

conclusion

Chrome Devtools provides Memory tools for Memory analysis, including Snapshot, TimeLine and Sample. We used the TimeLine tool to analyze the Memory allocation of strings in real time, proving the existence of string constant pool. And the memory differences between String literals and new Strings.

It is recommended to use String literals rather than new strings. There is still a gap in memory size.

During the proof process, we can also intuitively feel the huge benefits of the string constant pool.