Node.js 在数组中存储WebSocket消息时堆内存不足

Node.js 在数组中存储WebSocket消息时堆内存不足,node.js,websocket,heap-memory,Node.js,Websocket,Heap Memory,我正在Node.js中编写一个WebSocket客户机,我希望对消息数据执行异步操作(即存储在数据库中),但也要确保消息按接收顺序一次操作一条消息 为了实现这一点,我将消息推送到onMessage处理程序中的一个数组中,同时使用一个调用自身的函数将消息从数组中一次转移一个。大概是这样的: const flushQueue = async () => { const nextMessage = messageQueue.shift(); await doSomethingAsyn

我正在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消息集?

我几乎可以肯定问题在于您的尾部调用,而不是移动数组。节点和Javascript没有适当的尾部调用优化。一些和

没有尾部调用优化的长时间运行的循环最终将耗尽内存

我会删除这个自定义队列,并直接写入数据库

SQLite+驱动程序是一个很好的起点

//伪代码示例(未测试)
ws.on('message',函数传入(数据){
const stmt=db.prepare('插入列表(消息)值(?))
const result=stmt.run(data)//进程内同步写入
//做一些有结果的事情或其他事情
});