【问题标题】:Javascript/Node.js array memory managementJavascript/Node.js 数组内存管理
【发布时间】:2016-12-28 12:30:57
【问题描述】:

我有一个使用数组作为队列的场景,我对这个场景的内存有疑问。

首先,我在全局中创建一个数组对象,并创建一个生产者将元素不间断地推送到数组中。

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中手动释放内存?

【问题讨论】:

  • 内存会在垃圾收集器运行时被清除,而不是在你清空数组时立即清除。
  • var t = arr.concat(arr); 应该做什么?如果t 变量未在其他地方引用,则整行是多余的,但如果它在其他地方引用(不知何故,在代码中未显示),则对该数组的引用(其大小是arr was) 仍然存在,因此它将继续使用内存。
  • 生产者正在使用数组,你不能指望数组从内存中被清除。
  • 不。您正在使用全局数组。除非您停止 nodejs 进程,否则它不会清空内存。记住全局变量是邪恶的
  • @AkshayKhandelwal OP 的代码每秒创建一个新的空数组并将其分配给arr。不只有一个数组。 GC 正在清理未使用的数组及其内容。

标签: javascript arrays node.js memory


【解决方案1】:

这个问题的答案在 Barmar 的评论中。保留的内存在不再需要时不会立即释放。 JavaScript 依靠垃圾收集来检测未使用的引用并将它们释放回堆中,但垃圾收集是一个昂贵的过程,因此它只会每隔一段时间运行一次。

当我尝试运行您的代码时,内存使用量确实会增加一两分钟,然后在垃圾收集运行时突然恢复到原来的值。也许您只是看日志的时间不够长?

您可以手动运行垃圾收集并通过运行带有--expose-gc 标志的节点并执行global.gc() 来亲自查看这一点,但您应该在生产代码中这样做,除非您有一个非常很好的理由。

【讨论】:

  • 有点问题,我发现usage memory会回到原来的内存值,但是会比原来的多一点,大约10kb。每次都是这样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多