JavaScript V8 Engine

Source: Internet
Author: User
Tags abstract tree

First, browser kernel-rendering engine

Rendering is the process of building a mathematical model and generating an image based on a description or definition.

The main purpose of the browser kernel is to turn the page into a visual/audible multimedia result, often referred to as the rendering engine. Convert html/css/javascript text and other appropriate media type resource files to Web pages.

Inside the solid wireframe module is a common part of all porting, and the different vendors in the dashed box can implement it themselves. The following is an introduction:

WebCore is a shared section used by various browsers, including HTML parsers, CSS parsers, DOM, and SVG.

JavaScriptCore is the default engine for WebKit and is replaced by the V8 engine in the Google series.

WebKit Ports is a non-shared part of WebKit, due to differences in platform, third-party libraries and requirements, different migrations lead to inconsistent WebKit behavior, which is a key part of different browser performance and function differences.

WebKit embedded programming interface, for browser invocation, is closely related to porting, different porting has different interface specification.

The hierarchy of the browser kernel, the rendering engine parses the Web page resource, calls the third-party library to render the drawing.

From the above two figure you can see the internal composition of the rendering engine and the large module. WebCore, is responsible for parsing HTML, CSS Generation DOM tree and other rendering processes, JS engine is responsible for parsing and executing the JS logic process.

second, JavaScript engine1, JS engine and rendering engine relationship

  

  The relationship between the JavaScript engine and the rendering engine is as shown. The rendering engine uses the interface of the JS engine to process the logic code and get the results. The JS engine accesses the DOM and CSSOM (poor performance) in the rendering engine via a bridging interface.

2. JS Engine workflow

  

  JavaScript is essentially an interpreted language, and unlike a compiled language, it needs to be parsed over and over, while the compiled language is compiled at execution time, can be executed directly, and has a faster execution speed (as shown ).

  

Describes the process of JS code execution. The process does not look at first, a JS engine mainly consists of the following parts:

Compiler. The source code through lexical analysis, syntax analysis (you do not know the JS unknown origin) compiled into an abstract syntax tree, in some engines also contains the abstract syntax tree into byte code.

Interpreter. In some engines, the interpreter mainly receives the bytecode, interprets the execution of this bytecode, and also relies on the garbage collection mechanism.

JIT tool. Converts a bytecode or abstract syntax tree to a cost code.

Garbage Collector and Analysis tool (Profiler). Responsible for information in the garbage collection and collection engine to help improve engine performance and effectiveness.

iii. V8 Compilation and execution1. Data representation

In the JS language, only the base data type, Boolean, number, String, Null, Undefined, and others are objects.

In V8, the representation of a data is divided into two parts. The first part is the actual content of the data, they are variable length, and the type of the content is not the same, such as String, object, etc., the second part is the handle of the data, the size is fixed, and contains a pointer to the first part of the data. In addition to very few data such as Integer data, other content is requested from the heap to store memory, because the handle itself can store the integer type, but also can be quickly accessed.

2, handle handle

V8 need to be garbage collected, and need to move the data content, if the direct use of pointers will be problematic or need to be relatively expensive. There is no such problem with the handle, only the pointer in the handle can be modified, and the user is using a handle that does not change itself.

  

As can be seen, the size of a handle object is 4 bytes (32-bit machine) or 8 bytes (64-bit machine), unlike the JavaScriptCore engine, which is a handle that uses 8 bytes to represent data. Small integers (only 31 bits can be used) get the values directly in the value_ without having to be allocated from the heap.

Because the objects stored in the heap are all 4-byte aligned, the last two bits of the pointers to them are 00, which is not required by the two bits. In V8, they are used to represent the type of data contained in the handle.

  

The implementation of the object handle contains 3 members in the V8. The first one is to hide the class pointer, the hidden class created for the object, the second point to the property value that the object contains, and the third point to the element that this object contains.

3. Compilation process

Consists of two phases: Compile and execute. Another important feature is the postponement of the idea, which causes many JS code compilations to occur (in functional units) until the runtime is called, reducing the time overhead.

The JS code passes through the compiler, generates an abstract syntax tree, and generates native code directly from the JIT full code generator. Reduce the conversion time of the abstract tree to bytecode.

After generating the local code, for performance reasons, it is a gradual improvement process to gather some information through the Data Analyzer to help decide which local code needs to be optimized to produce more efficient local code.

4. Optimized rollback

The compiler makes optimistic and bold predictions that the code is stable and that the variable type does not change to produce efficient native code. When the engine finds that the type of some variables has changed, V8 will roll back the optimizations to the previous general situation.

As above, after the function ABC has been called many times, the Data Analyzer thinks that the type of the code within the function has been learned, but when the assignment to the UNKONWN variable occurs, V8 can only roll back the code to a common state.

Optimizing rollback is a time-consuming operation, and restoring previously optimized code to a code that is not specifically optimized is a very non-efficient process.

  

5. Hidden classes and inline caches

V8 uses the idea of class and offset placement to improve the algorithm for finding property values that would otherwise require string matching to be implemented using a mechanism similar to the offset location of the C + + compiler, which is the hidden class.

A hidden class is divided into groups (types), depending on how the object has the same property name and property value. For the same group, these property names and corresponding offset locations are saved in a hidden class, and the objects within the group share the information. Also, you can identify objects with different properties.

  

  

, two objects A, B are created using the constructor function. The two objects contain the same property names, and in V8 they are categorized as the same group, which is the hidden class, which has the same offset value in the hidden class. Objects A and B can share information about this grouping, and when they are accessed, they can be located and accessed based on the offset values of the hidden classes.

Because JavaScript is a dynamic type language, when adding code D.Z = 2. Then the B object will be a new hidden class, so that A and B will belong to different groups.

function Add (a) {return a.x};

The basic procedure for accessing an object's properties is to get the address of the hidden class, find the offset value based on the property name, and calculate the heap memory address of the property. This process is still time-consuming, and actually uses a caching mechanism called inline caching.

The basic idea is to cache the results of the previous lookup (hidden classes and offset values) and avoid the problem of multiple hash table lookups when re-accessing them.

Note: When there are multiple types of attribute values within an object, the probability of a cache error is much higher. Go back to the previous way to find the hash table.

  

iv. V8 Memory allocation

The main two points: 1, the memory of the use of 2, for the JS code garbage collection mechanism

1, small memory block zone class

Manages a series of small chunks of memory that are similar to the life cycle of these small memory, and can use a zone object.

The Zone object first applies a piece of memory to itself and then manages and allocates some small memory. When a small piece of memory is allocated, it cannot be reclaimed by zone and can only reclaim all the small memory allocated by the zone at once. For example: the memory allocation and use of the abstract syntax tree, after the build, will generate local code, and then its memory is fully recovered at once, very efficient.

However, there is a serious flaw, when a process requires a lot of memory, zone will need to allocate a lot of memory, but not timely recovery, will lead to memory shortage situation.

2. Heap Memory

V8 uses heaps to manage the data that JavaScript uses, as well as the generated code, hash tables, and so on. To make garbage collection easier, as with many virtual machines, V8 divides the heap into three pieces. Young generations, older generations, and large objects.

  

  

Young generational: Allocates memory space for newly created objects and often requires garbage collection. To facilitate the recycling of content in younger generations, it is possible to divide the younger generation into two halves, half for distribution, and the other half to replicate the objects that need to be retained before they are recycled.

Old age generational: save older objects, pointers, code, and more, as needed, for less garbage collection.

Large objects: For those who need to use more memory objects to allocate memory, of course, may also contain data and code, such as allocated memory, a page is allocated only one object.

When you declare a variable in code and assign a value, the memory of the object being used is allocated in the heap. If the requested heap free memory is not sufficient to allocate new objects, the heap memory will continue to be requested, knowing that the heap size reaches the V8 limit.

V8 Memory usage limit: Approximately 0.7G in a 64-bit system in the 1.4G,32 bit system. Sufficient to use in the browser page, there is insufficient in node, so that node cannot directly manipulate large memory objects, in the case of a node process, can not fully utilize the computer's memory resources.

There are two reasons for the memory limit, which prevents one page of the browser from consuming too much system memory resources, on the other hand, V8 the efficiency of garbage collection. For 1.5G of memory, do a small garbage collection takes more than 50 milliseconds, do a full amount of recycling even more than 1 seconds, this process will block the execution of the JS thread.

Five, garbage collection

V8 's garbage collection strategy is mainly based on the split-generation recycling mechanism. The garbage collection of memory is divided into different generations by the lifetime of the object, and then a more efficient algorithm is used for each memory.

1.  Cenozoic Scavenge (purge) algorithm

The main use of Cheney (name) algorithm. A garbage collection algorithm implemented by means of replication.

1, the Cenozoic heap memory is divided into two, each part of the space is called Semispace. One is in use called from space and the other is idle called to space.

2. When we allocate objects, we first allocate them in the From space.

3, garbage collection, check the from space of the surviving objects, whether it has experienced a clear recovery, the two to space has been used 25% (to ensure that the new allocation has enough space).

. 4. Copy these surviving objects into the to space. The space occupied by non-surviving objects will be freed.

5. After the copy is complete, the from space and the to space role take place the swap.

Note: The actual heap memory used is the sum of the two semispace space in the Cenozoic and the size of the memory used by the Laosheng generation.

How can I tell if an object survives? Scope? is a set of rules for storing and querying variables. This set of rules determines whether objects in memory can be accessed.

Characteristics:

The purge algorithm is a typical time-of-sacrifice algorithm that cannot be applied to all collections on a large scale, but is well suited for applications that are short-term in the Cenozoic life cycle.

2, Mark-sweep Laosheng Mark Clear

1. Mark the stage to traverse all objects in the heap and mark the living objects

2, clear the stage, only the object is not marked.

The biggest problem is that there is a discontinuous state after a mark cleanup. This memory fragmentation can cause problems with subsequent memory allocations. It is likely that when a large object is allocated, all of the fragmentation space cannot be completed and the garbage collection is triggered ahead of time, and this full-scale recovery is unnecessary.

3, Mark-compact Laosheng Mark Finishing

Developed on the basis of Mark removal, in the process of finishing

1. Move the Living object to a certain distance

2. After the move is complete, clean out the memory outside the boundary directly

4, Incremental marking increment mark

The process of garbage collection requires that the application logic be paused.

In order to reduce the pause time caused by the full amount of recovery, in the marking phase, the original breath to complete the action to change the increment mark. Garbage collection and application logic are performed alternately to the Mark phase. The maximum pause time is about 1/6 less.

Deferred cleanup and incremental grooming are also introduced to make cleanup and grooming actions incremental.

Vi. Efficient memory usage 1, scope

The function creates the corresponding scope (its own execution environment, and the variable object) each time it is called, and the local variables declared in the scope are allocated in the scope. After execution, the scope is destroyed, the death token is made, and the next garbage collection is released.

Active release of variables, dereference relationships:

If the variable is a global variable, the referenced object is resident memory (Laosheng generation) because the global scope needs to be freed until the process exits. You can delete a reference relationship by using Delete, or reassign a variable to a value. However, deleting an object's properties through delete in V8 may interfere with V8 optimizations.

Closures:

When the function execution ends, but the scope (variable object) still needs to be referenced, its variable object cannot be marked invalidated, and the occupied memory space will not be cleared for release. The release is gradual unless there is no longer a reference.

In normal JS execution, the memory that cannot be recovered immediately has closures and global variables in both cases. To prevent these variables from increasing indefinitely, the objects in the Laosheng generation increase, or even memory leaks.

2. Memory leaks

Substance: Objects that should be recycled are unexpectedly, not recycled, and become permanent objects in the Laosheng generation.

Typically, the cause of a memory leak is as follows:

1. Cache

Cache unlimited growth, long-term presence in the Laosheng generation, occupy a large amount of memory.

Policy: Increase the number and validity limit for the cache.

With out-of-process caching such as Redis, V8 cache limits are not consumed and caches can be shared between processes.

2, the queue consumption is not timely

JS can accomplish many special needs through the queue (array object). In consumer-producer models, they often act as intermediate products. When the consumption rate is lower than the generation speed, it will accumulate.

For example: logging, when using inefficient database writes, it is possible to write event stacks.

Strategy: Use an efficient consumption approach. Monitor the length of the queue.

3, the scope can not be released

For the use of a large number of closures, be aware of releasing scopes.

JavaScript V8 Engine

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.