When I interview candidates, even if a front-end graduate, asked him the allocation of memory in javascript, can answer stack memory, heap memory. But when asked how the heap is allocated, 80% of the interviewees couldn’t answer.

V8 allocation of memory

Js objects are stored in the heap, so where exactly?

The V8 engine divides the heap into two distinct regions, one called the old generation and the other the Young generation.

Even among objects in the Cenozoic, they have different grades, which are further divided into the nursery and intermediate levels.

In a game like Red Alert, the American soldier is born as a first class soldier. After a fierce battle, the surviving soldier is promoted to second class, and after another battle, he or she is promoted to third class.

The same is true for the primary and intermediate generation of JS.

In JS, when an object is allocated memory for the first time, it is allocated to the nursery generation of the new generation, which is equivalent to the weakest soldier.

This object, if it survives the first round of garbage collection. So, we moved him to intermediate, which is to become a second class soldier.

If the object survives the next garbage collection, then we move it from intermediate to senior-level, where it is promoted to level 3.

Why would V8 do that?

There’s an important concept in garbage collection: The Generational Hypothesis. In other words, most JS objects are cannon fodder, which will not survive a round of garbage collection and will remain in memory for a very short time. In other words, from a garbage collection point of view, many objects become inaccessible as soon as memory is allocated. As shown below:

Since there is such a difference between short-lived and long-lived JS objects, V8 separates them and adopts different garbage collection strategies.

When the javascript main thread is running properly, the memory footprint is increasing. Growth triggers a limit, and when that limit is triggered, garbage collection is triggered. For the new generation and the old generation, V8 has two garbage collectors to handle.

Two garbage collectors in V8

The V8 is built on two recyclers, the Full Mark-Compact and Scavenge. The two garbage collectors are independent of each other.

The primary garbage collector collects garbage from the old generation (and also takes care of a portion of the new generation heap), and the secondary garbage collector collects garbage from the new generation.

From-Space / To-Space

For a para-garbage collector, two memory Spaces are related: from-space and to-space.

And don’t get confused, from-space and to-space are not the same concepts as primary and intermediate generation.

From-space and to-space can be understood as the actual operational memory space; The primary and intermediate generations represent the hierarchy of an object. From-space and to-space are always empty and in use. Even objects in from-space may be junior (private first class) or intermediate (private second class).

Next, take a look at the process of the paralgarbage collector.

Side garbage collector step

The first step is marking

The purpose of this step is to determine which objects in the GC cycle need to be reclaimed.

How do you tell? Just to see if the object can be found.

Marking starts from the root of the search, that is, the top layer of the execution stack, the global object to start the search, and then find the reference of the object, and then the reference of the object reference, a layer of recursive search.

If an object can be accessed, it is considered alive and should not be reclaimed. Otherwise, it will be recycled.

Next, we start a garbage collection cycle.

Step 2

In step 2, V8 moves objects from from-space to to-space that will not be garbage cleaned up. This means that only a small percentage of objects are successfully evacuated to to-space without being garbage cleaned up. Most objects left in from-space are destroyed as cannon fodder.

Not to be confused with copy object Pointers in JS code, here is the lower level binary data. The process of copying is the process of copying binary data in that piece of memory.

At the end of this step, also known as the evacuation step, memory looks like this:

On the right of the image above, the objects evacuated to the to-space successfully survive the first round of garbage collection, marking their squares (i.e. small circles for each block), marking their progression from the primary generation to the intermediate generation.

Step 3

Next, step 3 is called updating the reference pointer.

We find that the reference pointer to the object in JS still refers to the old from-space space, and we need to update these references to the to-space space.

After the end, as shown below:

Step 4

Next, we swap to-space and from-space. To-space moves to the left and becomes the next from-space, and from-space moves to the right and becomes the next to-space

Second round of garbage collection

After the first round of garbage collection, js continues and some newly allocated primary generation objects are pushed into from-space behind the surviving veteran intermediate generation objects from the previous round, as shown in the red arrows below:

The second round of garbage collection process, similar to the first round, will not be repeated.

The key point of the second round of garbage collection is that the middle generation of surviving veterans in from-space copies the old generation on the far right and is promoted to the old generation. New recruits from the junior generation are copied to the To-space and also marked as intermediate generation, as shown below:

Secondary garbage collector with concurrent processing

Today, V8 uses concurrent cleanup in next-generation garbage collection.

What? Concurrent?

Yes, you heard me right. Although javascript is a single-threaded language, it simply means that most of the code written by javascript programmers runs on a single thread. However, the host environment of javascript language, such as V8 engine, is the execution environment of javascript, and it can create many threads to assist the work of the main thread of javascript. We refer to these other helper threads as helper threads, and the javascript executing threads are the main threads.

The task of evacuating the surviving object to the to-space, which is executed concurrently by the main thread and the helper thread, is to minimize GC time for D.

  • Each worker thread and main thread moves live objects To to-space. Atomic operations must be ensured every time a live object is attempted To move To a to-space.

  • It is possible for different worker threads To find the same object through different paths and try To move it To the to-space. Whenever a worker thread succeeds in moving an object To a to-space, it must update the pointer To that object.

Summary of secondary garbage collector

  • Because of the theory of the generation hypothesis, only a small percentage of JS objects will survive, so in the garbage collector, only a small percentage of objects will be evacuated and copied to the to-space space, and most of the other objects will be destroyed.

  • From-space and to-space are only used, so space costs a lot. Typically, space is exchanged for time.

  • Helper thread concurrent help withdrawal

Main garbage collector

As mentioned above, new generation objects will be promoted to old generation if they survive two consecutive rounds of GC.

Next, let’s look at how old generation objects are processed by the main garbage collector.

The garbage collection of the old generation will go through the following processes: marking, sweeping and compacting.

marking

The marking process is described in the secondary garbage collector section above

Clean the

Once marked, V8 knows which objects will not be accessed and thus need to be reclaimed. The position occupied by these recycled objects, people walk tea cooling, is empty down, become a vacant position.

V8 manages these free locations so that the next time a new object arrives, it can be placed in a spatial location.

V8 sweeps these free positions into a table called FreeList to record them, a process known as cleaning, which can be done silently by a worker thread in the background.

The compression

If you know anything about computer operating systems, you know the concept of fragmentation.

Compression means that we want to take the data in memory, squeeze it together, get a little bit closer together, and merge the gaps between them, the fragments, into a larger contiguous space. That way, the next time a larger object comes along, you’ll have enough space to store it.

Secondary threads process concurrently

In the main garbage collector, there are also multiple helper threads to improve efficiency.

First, the helper thread starts marking concurrently.

Then, when the helper thread has finished its work, the main thread will pause to finalize marking and start cleaning tasks.

The final marker is that the main thread does a quick recheck at the root to see if any of the helper threads have missed anything, to make sure that all objects have been scanned correctly

If the check is OK, the main thread and some of the worker threads work together to perform Compact and update operations.

The other part of the helper thread, which performs the cleanup concurrently, does not affect the collation of parallel memory pages or JavaScript execution.

When all this is done, the main thread starts executing the code again.

Idle garbage collector

There is no way for JavaScript programmers to manipulate the garbage collector directly.

To solve this problem, V8 introduced the concept of idle time. Our page runs inside the browser, which executes some animations at 60 frames per second, and the browser has about 16.6 milliseconds to render each frame of the animation.

If the rendering is done ahead of time, the browser triggers the garbage collector during the idle time before the next frame.

conclusion

The V8 garbage collector project has come a long way since it became its own project. It has been years of effort to add parallel, concurrent, and incremental garbage collection techniques to existing garbage collectors, and some success has been achieved.

Moving a large number of tasks to the background, greatly reducing the main thread pause time, improve the page lag, so that animation, scrolling and user interaction more smooth. Scavenger collector reduces the garbage collection time of the new generation by approximately 20%-50%. The idle garbage collector reduces the JavaScript heap memory by 45% when the Gmail Web application is idle. Concurrent tag cleanup can reduce mainthread pause times in large WebGL games by up to 50%.

Most JavaScript developers don’t need to think about garbage collection, but understanding some of the internals of garbage collection can help you understand memory usage and the appropriate coding paradigm. For example, from the generational structure of V8 heap memory and the garbage collector’s point of view, the cost of creating objects with short lifetimes is very low, but the cost of creating objects with long lifetimes is high. These patterns are applicable to many dynamic programming languages, not just JavaScript.

Bytedance is hiring a lot of people

Bytes to beat (hangzhou) | Beijing | Shanghai a lot of hiring, welfare super salaries seconds kill BAT, not clock, every day to work in the afternoon tea, free snacks unlimited supply, free meals (I read the menu, Big gate crab, abalone, scallop, seafood, grilled fish fillet, beef, curry and spicy crayfish), free gym, touch bar, 15-inch top, new MBP, monthly rental allowance. This is really a lot of opportunities, the number of research and development after the expansion of N times, good technical atmosphere, cattle, less overtime, still hesitate what? Send your resume to the email below, now!

Just a small part of the JD link below, more welcome to add wechat ~

The front end of jd: job.toutiao.com/s/bJM4Anjob…

The back-end jd: job.toutiao.com/s/bJjjTsjob…

Jd: test job.toutiao.com/s/bJFv9bjob…

Jd: job.toutiao.com/s/bJBgV8job…

The front-end intern: job.toutiao.com/s/bJ6NjAjob…

The back-end intern: job.toutiao.com/s/bJrjrkjob…

Continue to recruit a large number of front-end, server, client, testing, products, internship recruitment are wide to

Resume send [email protected], it is suggested to add wechat Dujuncheng1, you can chat to chat about life, please indicate from nuggets and where to deliver the post