垃圾收集器是否处理 javascript 中的覆盖值或 "nullified" 记忆值?

Does garbage collector work on overriden or "nullified" memoized values in javascript?

很抱歉有人问过类似的问题,搜索没有找到。

假设我有一个函数可以在 js 中创建一个大的记忆值,在这个例子中是一个包含 100 万个随机数的数组,并调用该函数两次,所以我有两个大数组。

  const memoizedValue = () => {
    const val = [...Array(1000000)].map((_, i) => i + Math.random())
    const valAtIndex = i => val[i];
    return valAtIndex;
  }
  let valAtIndex1 = memoizedValue();
  console.log(valAtIndex1(1000)) // 1000.9215271184725
  console.log(valAtIndex1(1001)) // 1001.123987792151
  let valAtIndex2 = memoizedValue();
  console.log(valAtIndex2(1000)) // 1000.8830808003901
  console.log(valAtIndex2(1001)) // 1001.3989636036797

如果清除对实例的引用,我是否会删除数组?如果我这样做,垃圾收集器是否会清除数组的内存(假设我没有任何其他实例):

valAtIndex1 = (i) => i;
console.log(valAtIndex1(1000)) // 1000
console.log(valAtIndex1(1001)) // 1001

如果我分配值 null,这会清除数组的内存吗?

valAtIndex1 = null;

如果您释放对您在 valAtIndex1 中放入的函数的所有引用(例如,通过执行 valAtIndex1 = x 其中 x 可以是任何字面意思,只要它不是值 valAtIndex1 已经包含在其中 - nullundefined42、...),这会释放该函数对创建它的上下文的引用,这反过来释放上下文对大数组的引用。垃圾收集器可以自由回收该内存。

例如:

let valAtIndex = memoizedValue();
console.log(valAtIndex(0)); // 1.3753751200626736 or whatever
valAtIndex = null;          // Releases the reference

在评论中,您似乎特别担心用另一次调用 memoizedValue 的结果覆盖变量的值。这绝对没问题:

let valAtIndex = memoizedValue(); // Creates array A and function A accessing it
console.log(valAtIndex(0));       // 1.3753751200626736 or whatever
valAtIndex = memoizedValue();     // Creates array B and function b accessing it,
                                  // releasing the reference to function A
console.log(valAtIndex(0));       // 1.6239617464592875 or whatever

旁注:您创建大型数组的代码将创建一个不必要的临时大型数组(您使用数组文字创建的那个),并且可能有两个(您使用 [= 创建的那个) 21=] 可能会为所有一百万个数组元素保留内存;例如,它在 V8 中会这样做,即使数组是空的)。相反:

const val = Array.from({length: 1000000}, (_, i) => i + Math.random());

将数组分配给 null undefined"" 将允许它被垃圾收集器清除。 Javascript 允许您以这种方式直接管理垃圾收集器。使用完后,只需将其指定为上述值之一,它就会自动为您清除。