Исчерпание памяти кучи при хранении сообщений WebSocket в массиве - PullRequest
0 голосов
/ 07 мая 2020

Я пишу клиент WebSocket в Node.js, и я хочу выполнять асинхронные операции с данными сообщения (т. Е. Сохранять в базе данных), но также обеспечивать, чтобы сообщения обрабатывались по одному в порядке, указанном в которые они были получены.

Для этого я отправляю сообщения в массив в моем обработчике 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 в очереди с эффективным использованием памяти на неопределенный срок?

1 Ответ

1 голос
/ 07 мая 2020

Я почти уверен, что проблема в вашем хвостовом вызове, а не в сдвиге массива. Узел и Javascript не имеют надлежащей оптимизации хвостового вызова. Некоторая статистика и публикует TCO .

Длительный l oop без оптимизации хвостовых вызовов в конечном итоге исчерпает память.

Я бы отбросьте эту настраиваемую очередь и напишите прямо в базу данных.

SQLite + better-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
});
...