Остановить NodeJS 'readdir из утечки памяти - PullRequest
0 голосов
/ 26 февраля 2020

Я недавно написал Интервал в NodeJS, который проверяет содержимое папки каждые X секунд. Это asyn c, поэтому он запускается рядом с остальным кодом для обновления индексов и содержимого.
ОС - это Debian 9 с узлом v10.15.2 и npm 5.8.0.

  return await new Promise(resolve => {
    const interval = setInterval(() => {
      console.log("Checking for new files...")
      fs.readdir("folder", (err,files) => {
        if(files.length != cur_files.length){
          console.log("New files detected!")
          updateIndexes(files);
        }else{
          console.log("Folder is up-to-date!")
        }
      });
    },10000);
  });
} 

Я заметил, что при тестировании с таймером с небольшим интервалом он медленно, но неуклонно увеличивает использование памяти на ~ 0,1 МБ каждые несколько минут. Я знаю, что это не так много с большим интервалом, но он будет увеличиваться со временем, если я запусту его без перезапуска.

Другая часть кода уже использует Stream для частого чтения / записи файлов, Должен ли я сделать что-то подобное с readdir?
Это ошибка или просто плохая практика?

Заранее спасибо!

BR Крис

1 Ответ

0 голосов
/ 26 февраля 2020

Почему вы возвращаете Обещание, которое никогда не разрешается?

Сборщик мусора будет периодически собирать не связанные объекты, но помещение этого кода в неразрешенное Обещание, подобное этому, может помешать G C собирать их, потому что он думает, что нуждается в них, когда Обещание разрешается.

Попробуйте:


return (() => {
  let fileCount = 0 // hide variable because State Machine
  return setInterval(() => {
      console.log("Checking for new files...")
      fs.readdir("folder", (err,files) => {
        if(files.length != fileCount){
          console.log("New files detected!")
          fileCount = files.length;
          updateIndexes(files); 
        }else{
          console.log("Folder is up-to-date!")
        }
      });
    },10000)
  })()
} 

Это конечный автомат, и он скрывает свое состояние (fileCount) внутри замыкания.

Возвращает дескриптор того, что вы можете отменить с помощью cancelInterval.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...