前端面试题-js(四)

发布时间 2023-07-12 10:18:00作者: 木子李丫

1.垃圾回收

对于开发者来说,JavaScript 的内存管理是自动的、无形的。我们创建的原始值、对象、函数……这一切都会占用内存。

可达性(Reachability)

JavaScript 中主要的内存管理概念是 可达性

简而言之,“可达”值是那些以某种方式可访问或可用的值。它们一定是存储在内存中的。

  1. 这里列出固有的可达值的基本集合,这些值明显不能被释放。

    比方说:

    • 当前执行的函数,它的局部变量和参数。
    • 当前嵌套调用链上的其他函数、它们的局部变量和参数。
    • 全局变量。
    • (还有一些内部的)

    这些值被称作 根(roots)

  2. 如果一个值可以通过引用链从根访问任何其他值,则认为该值是可达的。

    比方说,如果全局变量中有一个对象,并且该对象有一个属性引用了另一个对象,则  对象被认为是可达的。而且它引用的内容也是可达的。

在 JavaScript 引擎中有一个被称作 垃圾回收器 的东西在后台执行。它监控着所有对象的状态,并删除掉那些已经不可达的。

垃圾回收算法:

JavaScript具有自动垃圾收集机制,也就是说,执行环境将负责管理代码执行过程中使用的内存。

在JavaScript中,如果一个对象不再被引用,那么这个对象就会被垃圾回收器回收,当对象被回收之后,这块内存就可以被再次使用。

JavaScript有两种垃圾回收机制:

1. 标记清除(Mark-and-sweep):这是JavaScript中最常见的垃圾收集方式,当变量进入环境(例如,在函数中声明一个变量)时,就将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。

2. 引用计数(Reference counting):引用计数是另一种垃圾回收策略,引用计数的含义是跟踪每个值被引用的次数。当声明了一个变量并将一个引用类型值赋值给该变量时,这个值的引用次数就是1。如果同一个值又被赋值给另一个变量,那么这个值的引用次数就增加了1。相反,如果包含对这个值引用的变量又取得了另外一个值,那么这个值的引用次数就减少1。当这个值的引用次数变为0时,说明没有办法访问这个值了,因此就可以将其占用的内存空间回收回来。这样,当垃圾收集器下次运行时,它就会释放那些引用次数为0的值所占用的内存。

这两种方式都有自己的优缺点,但标记清除是目前主流的垃圾回收方式,主要的原因是它不会导致循环引用的问题。