Javascript/Node.js阵列内存管理
我有一个使用数组作为队列的场景,我对这个场景有一个关于内存的问题 首先,我在全局中创建了一个数组对象,并创建了一个生产者来不间断地将元素推送到数组中Javascript/Node.js阵列内存管理,javascript,arrays,node.js,memory,Javascript,Arrays,Node.js,Memory,我有一个使用数组作为队列的场景,我对这个场景有一个关于内存的问题 首先,我在全局中创建了一个数组对象,并创建了一个生产者来不间断地将元素推送到数组中 var arr = []; function runningProducer() { setInterval(itemProducer, 50); function itemProducer() { var item = generateItem(); arr.push(item); } function gen
var arr = [];
function runningProducer() {
setInterval(itemProducer, 50);
function itemProducer() {
var item = generateItem();
arr.push(item);
}
function generateItem() {
return { a: Math.random(), };
}
}
然后,我创建一个客户,在1秒内清除阵列
function runningCustomer() {
setInterval(clearQueue, 1000);
function clearQueue() {
var t = arr.concat(arr);
arr = [];
}
}
运行上述函数一段时间后,我发现内存一直在增长
setInterval(() => {
var mem = process.memoryUsage();
console.log(mem);
}, 2000);
我认为数组应该在设置为空后释放内存,但不能。
请给我一些关于这个问题的建议,有没有办法用javascript手动释放内存?这个问题的答案在Barmar的评论中。保留内存不再需要时不会立即释放。JavaScript依靠垃圾收集来检测未使用的引用并将其释放回堆,但垃圾收集是一个昂贵的过程,因此它只能每隔一段时间运行一次 当我尝试运行您的代码时,内存使用确实会增加一两分钟,然后在垃圾收集运行时突然恢复到其原始值。也许你只是看日志的时间不够长
您可以手动运行垃圾收集并亲自查看,方法是使用
--expose gc
标志运行节点并执行global.gc()
,但您应该不要在生产代码中执行此操作,除非您有非常好的理由。当垃圾收集程序运行时,内存将被清除,在清空数组时不会立即执行。什么是var t=arr.concat(arr)代码>应该怎么做?如果t
变量未在别处引用,则整行是冗余的,但如果它在别处引用(不知何故,在未显示的代码中),则对该数组的引用(其大小是arr
的两倍)仍然存在,因此它将继续使用内存。生产者正在使用该数组,不能期望从内存中清除阵列。No。您正在使用全局数组。除非停止nodejs进程,否则它不会清空内存。记住,全局变量是evil@AkshayKhandelwalOP的代码正在创建一个新的空数组,并每秒将其分配给arr
。不仅仅是一个数组。GC正在清理未使用的数组及其内容。有一个小问题,我发现使用内存会回到原始内存值,但会比原始内存值略高,大约10kb。每次都是这样。