垃圾收集器是否处理 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
已经包含在其中 - null
、undefined
、42
、...),这会释放该函数对创建它的上下文的引用,这反过来释放上下文对大数组的引用。垃圾收集器可以自由回收该内存。
例如:
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 不 允许您以这种方式直接管理垃圾收集器。使用完后,只需将其指定为上述值之一,它就会自动为您清除。
很抱歉有人问过类似的问题,搜索没有找到。
假设我有一个函数可以在 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
已经包含在其中 - null
、undefined
、42
、...),这会释放该函数对创建它的上下文的引用,这反过来释放上下文对大数组的引用。垃圾收集器可以自由回收该内存。
例如:
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 不 允许您以这种方式直接管理垃圾收集器。使用完后,只需将其指定为上述值之一,它就会自动为您清除。