Understanding Memory Layout and Size Calculation in V8

Understanding Memory Layout and Size Calculation in V8


JavaScript engines like V8 go to great lengths to optimize the handling of strings, which are fundamental to many web applications. In this article, we'll explore the memory layout and size calculation for strings in V8, focusing on ASCII and non-ASCII characters.

Object Header: Every string in V8 is represented as an object, which includes an object header containing essential information about the string:

  1. Shape Descriptor: 4 bytes
  2. Hash: 4 bytes
  3. Length: 4 bytes Total: 12 bytes

Character Storage: For strings containing only ASCII characters, each character is stored using a single byte. Let's consider a string with five ASCII characters ('1', '2', '3', '4', '5'):

Character Storage: 5 bytes

Padding: To align the total size of the object header and character storage to the nearest multiple of 4 bytes (pointer size), padding bytes are added:

Padding needed: 3 bytes Total size calculation: 12 bytes (header) + 5 bytes (characters) + 3 bytes (padding) = 20 bytes

For strings containing non-ASCII characters, such as Tamil or other non-Latin scripts, V8 uses two bytes per character to accommodate a wider range of Unicode characters. This allows V8 to correctly represent and handle characters from various languages and writing systems that require more than one byte for encoding. Check out my blog for more insights The Art of Converting Data into Binary Form

Example:

Let's break it down:

  • "?" (Tamil letter "tha") requires 2 bytes.
  • "?" (Tamil letter "ma") requires 2 bytes.
  • "?" (Tamil vowel sign "i") requires 2 bytes.
  • "?" (Tamil letter "zha") requires 2 bytes.

So, the total size for the string "????" would be 4×2=8 bytes. Each character occupies 2 bytes due to being outside the ASCII range.

Shallow Size vs. Retained Size

  • Shallow Size: The size of the string object itself, including the object header and pointers to its properties.
  • Retained Size: The total memory consumed by the string object, including the memory used by its properties.

Example: Person Object

Consider a Person object with firstName, lastName, and age properties:

function Person(firstName, lastName, age) {

    this.firstName = firstName;

    this.lastName = lastName;

    this.age = age;

}

var people = [];

for (let i = 0; i < 10; i++) {

    people.push(new Person('John', 'Doe', 30));

}        

Shallow Size for john object: 16 bytes

  • Object Header: 12 bytes
  • firstName pointer: 4 bytes

Shallow Size for deo object: 16 bytes

  • Object Header: 12 bytes
  • lastName pointer: 4 bytes
  • age property: 0 bytes (assuming age is an immediate small integer (`smi`))

Shallow Size for Person object: 24 bytes

  • Object Header: 12 bytes
  • firstName pointer: 4 bytes
  • lastName pointer: 4 bytes
  • age pointer: 4 bytes

Retained size for Person object: 240 bytes

Since there are 10 Person objects in the people array, the total retained size for all Person objects would be:

10 objects * 24 bytes = 240 bytes


memory representation in developer tools

Conclusion: Understanding the memory layout and size calculation for strings in V8 provides insights into how JavaScript engines optimize string handling. By efficiently managing memory for strings, V8 enhances the performance of web applications, especially those involving extensive string operations or internationalization.

要查看或添加评论,请登录

Srikanth K的更多文章

社区洞察

其他会员也浏览了