MST

星途 面试题库

面试题:JavaScript 生成器内存管理:生成器与垃圾回收机制的交互

深入阐述JavaScript生成器与垃圾回收机制之间的交互原理。例如,当一个生成器对象失去所有引用时,垃圾回收器是如何判定并回收其占用内存的,在这个过程中生成器内部状态、闭包等因素会产生怎样的影响?请结合具体代码示例说明。
13.9万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

JavaScript生成器与垃圾回收机制交互原理

  1. 垃圾回收机制基础:JavaScript采用标记 - 清除算法为主的垃圾回收策略。垃圾回收器定期扫描内存中的对象,标记所有从根对象(如全局变量、当前执行栈中的变量等)可达的对象,然后清除未被标记的对象,回收其占用的内存。
  2. 生成器对象失去引用时的回收:当一个生成器对象失去所有引用时,它就变成了不可达对象。垃圾回收器下次扫描时,会将其标记为可回收对象。例如:
function* myGenerator() {
    yield 1;
    yield 2;
}
let gen = myGenerator();
// 这里假设gen是唯一引用生成器对象的变量
gen = null; 
// 此时生成器对象失去引用,垃圾回收器下次扫描会将其回收
  1. 生成器内部状态的影响:生成器内部有自己的状态,比如暂停位置、局部变量等。当生成器对象失去引用,这些内部状态所占用的内存也会随着生成器对象的回收而被释放。例如:
function* innerGen() {
    let localVar = 'Hello';
    yield localVar;
}
let innerGenObj = innerGen();
innerGenObj.next();
innerGenObj = null; 
// 此时不仅生成器对象被回收,localVar占用的内存也被回收
  1. 闭包的影响:如果生成器内部存在闭包,情况会稍复杂。闭包会使内部函数对外部作用域的变量保持引用。例如:
function outer() {
    let outerVar = 'outerValue';
    function* innerGen() {
        yield outerVar;
    }
    return innerGen;
}
let genFunc = outer();
let genObj = genFunc();
// 即使genObj失去引用,如果闭包(innerGen函数)仍然存在对outerVar的引用
// outerVar不会被回收,直到闭包也不再可达
genObj = null; 
// 此时如果没有其他对闭包的引用,垃圾回收器会回收整个结构包括outerVar

当生成器对象失去所有引用,满足垃圾回收条件时,其内部状态和闭包相关的内存,若也随着生成器对象变得不可达,都会被垃圾回收器回收。