前端V8垃圾回收机制

V8是一款开源的JavaScript引擎,由Google开发。

它是Chrome浏览器的核心组件之一,并且被许多Node.js应用程序使用。V8引擎具有内置的垃圾回收机制,用于自动管理JavaScript程序中的内存分配和释放。

V8的垃圾回收机制主要包括两个部分:分代垃圾回收标记-清除算法。下面是它们的详细解释:


1.分代垃圾回收:

V8将内存分为新生代和老生代两个部分。新生代是指刚分配的内存,通常包含了生命周期较短的对象。老生代是指已经存在一段时间的内存,通常包含了生命周期较长的对象。因为新生代和老生代中的对象的寿命不同,所以V8使用不同的垃圾回收策略来管理它们。

对于新生代中的对象,V8使用Scavenge算法进行垃圾回收。Scavenge算法是一种基于复制的算法,它将内存分为两个相等的区域:From空间和To空间。当一个对象被创建时,它被分配在From空间中。当From空间满了之后,V8将使用Scavenge算法将From空间中的存活对象复制到To空间中。然后,V8将From空间和To空间交换,这样To空间就成为了新的From空间。这个过程被称为垃圾回收的“Scavenge”阶段。这种方式可以快速地回收内存,并且可以保证新生代中的对象的寿命较短,因此需要较少的垃圾回收时间。

对于老生代中的对象,V8使用Mark-and-Sweep算法进行垃圾回收。Mark-and-Sweep算法是一种标记-清除算法,它遍历所有的对象,并标记那些仍然在使用中的对象。然后,V8清除那些没有被标记的对象。这样就可以回收那些生命周期较长的对象,从而避免了内存泄漏。


2.标记-清除算法:

标记-清除算法是一种常见的垃圾回收算法,它遍历所有的对象,并标记那些仍然在使用中的对象。然后,它清除那些没有被标记的对象。这个过程需要暂停JavaScript程序的执行,因此会影响程序的性能。

V8使用增量标记算法来优化标记-清除算法的性能。增量标记算法将标记-清除算法分成多个阶段,每个阶段执行一小部分标记操作,然后让JavaScript程序执行一段时间,直到下一个标记阶段开始之前。这样就可以将垃圾回收的时间分散到多个时间段中,从而减少对程序性能的影响。

此外,V8还使用了一些其他的优化策略,例如对象晋升(Object Promotion)和内存压缩(Memory Compaction)。

对象晋升是指当一个对象在多次垃圾回收过程中存活下来时,它会被移动到老生代中。
内存压缩是指当V8在进行垃圾回收时,会尽可能地将存活对象移动到一起,从而减少内存碎片,提高内存使用效率。

总的来说,V8的垃圾回收机制是非常复杂和高效的,它可以自动管理JavaScript程序中的内存分配和释放,从而减少了程序员的负担,提高了JavaScript程序的性能和可靠性。


Q:From空间中的存活对象复制到To空间中,From里面的对象会清空吗?

A:在V8的垃圾回收机制中,当From空间中的存活对象被复制到To空间中后,并不会对From空间中的对象进行清空。

相反,V8会将整个From空间视为“垃圾”,这意味着From空间中的所有对象都可以被回收。

当垃圾回收的“Scavenge”阶段结束后,V8会将From空间和To空间的角色互换。这意味着原来的To空间现在成为了新的From空间,而原来的From空间则成为了新的To空间。这个过程被称为“垃圾回收的反转”(Garbage Collection Flip)。

在反转过程中,V8会丢弃原来的From空间,因为它已经被视为垃圾了。这样,To空间就成为了新的From空间,而原来的From空间中的对象也不会被清空。这种方式可以快速地回收内存,并且可以保证新生代中的对象的寿命较短,因此需要较少的垃圾回收时间。

需要注意的是,当From空间中的对象被复制到To空间中时,如果某个对象在To空间中没有足够的空间进行复制,那么这个对象就会被移动到老生代中。这种情况下,V8会将这个对象标记为“晋升”(Promotion),并将其移动到老生代中进行垃圾回收。

posted @ 2023-04-23 17:18  脆皮鸡  阅读(766)  评论(0)    收藏  举报