在数组中存储 WebSocket 消息时,堆内存耗尽。

问题描述 投票:0回答:1

我正在 Node.js 中编写 WebSocket 客户端,我想对消息数据执行异步操作(即存储在数据库中),但同时也要确保按照收到消息的顺序一次一个地操作。

为了达到这个目的,我在onMessage处理程序中把消息推送到一个数组中,同时使用一个调用自己的函数把消息从数组中移出。就像这样。

const flushQueue = async () => {

  const nextMessage = messageQueue.shift();

  await doSomethingAsync(nextMessage); // i.e. store in db, etc.

  flushQueue();
}

撇开我的系统是否能跟上的问题不谈,这个方法很好用, 除了脚本最终会用完堆内存。一个简单的测试表明,将一个元素从数组中移出,实际上 增加 而我的假设是,它减少了所使用的内存。

const a = [1,2,3,4,5,6];

a.shift();
a.shift();

console.log(process.memoryUsage());

为什么从数组中删除一个元素会增加进程使用的内存量?我如何以节省内存的方式无限期地存储我的一组排队的 WebSocket 消息?

node.js websocket heap-memory
1个回答
1
投票

我几乎可以肯定问题出在你的尾部调用上,而不是移动数组。Node和Javascript没有适当的尾部调用优化。一些 统计学在TCO上任职.

长时间运行的循环如果没有尾部调用优化,最终会耗尽内存。

我会放弃这个自定义队列,直接写到数据库。

SQLite + 更好的-sqlite3 司机是一个好的开始。

// pseudo-code example (not tested)
ws.on('message', function incoming (data) {
  const stmt = db.prepare('INSERT INTO list(message) VALUES(?)')
  const result = stmt.run(data) // synchronous in-process write
  // do something with result or something else
});
© www.soinside.com 2019 - 2024. All rights reserved.