Анализ памяти nodejs с потоковым API и без него

#javascript #node.js #memory #stream #aws-sdk

Вопрос:

узел v14.17.0

Я пытаюсь протестировать потребление памяти с использованием потоков и без них. Основная цель состоит в том, чтобы найти показатель, который четко покажет преимущества использования stream.

В настоящее время результаты выглядят одинаково:

ТЕСТ № 1: чтение файла без потока

 test('read file without stream and upload to s3', async () => {
    const fileContent = fs.readFileSync(path.join(__dirname, './benda.js'), 'utf8');
    await _uploadFile(`${FILE_NAME}`, bucket, fileContent);
    const used = process.memoryUsage();
    for (let key in used) {
        console.log(`${key} ${Math.round(used[key] / 1024 / 1024 * 100) / 100} MB`);
    }
})
 

результат № 1:

     rss 1541.91 MB
    heapTotal 538.3 MB
    heapUsed 535.07 MB
    external 482.39 MB
    arrayBuffers 0.1 MB
 

ТЕСТ № 2: создайте поток чтения и загрузите его в s3

 test('create read stream and upload to s3', async () => {
    const readStream = fs.createReadStream(path.join(__dirname, './benda.js'));
    await _uploadFile(`${FILE_NAME}`, bucket, readStream);
    const used = process.memoryUsage();
    for (let key in used) {
        console.log(`${key} ${Math.round(used[key] / 1024 / 1024 * 100) / 100} MB`);
    }
});


const _uploadFile = async(fileName, bucket, streamOrContent) => {
    const command = new PutObjectCommand({
      Bucket: bucket,
      Key: fileName,
      Body: streamOrContent
    });
    
    const res:PutObjectCommandOutput = await s3Client.send(command);
    return res;
  };
 

результат № 2:

 rss 1543.93 MB
heapTotal 539.8 MB
heapUsed 536.39 MB
external 485.05 MB 
arrayBuffers 3.39 MB
 

Это выглядит примерно так же, размер файла ~504 МБ

Пожалуйста, дайте мне знать, чего мне здесь не хватает? или мой тест неверен?

Комментарии:

1. Почему вы думаете, что чтение файла с локального диска-это та же операция, что и загрузка файла в s3, и, следовательно, должно использовать тот же объем временной памяти? Это совершенно разные пути кода, реализованные совершенно по-разному. Неудивительно, что они могут использовать другой объем памяти для выполнения своей работы.

2. Спасибо за комментарий, я обновил вопрос, загрузив файл в s3 и в тесте № 1. все равно получаю тот же результат. У вас есть лучший вариант использования для проверки использования памяти?

3. Какую проблему вы пытаетесь здесь решить? Вы измерили, что два разных пути кода (один с использованием потока, другой считывает весь файл в память) используют немного другой объем памяти в одном конкретном тесте. Это ни в малейшей степени не удивительно. Есть ли здесь реальная проблема? Все это использование памяти также должно быть только временным, поэтому, как только вы больше не будете использовать эти переменные и операция будет выполнена, сборщик мусора восстановит эту память как доступную для повторного использования при будущих выделениях Javascript.

4. Я собираюсь загружать большие объемы данных из разных типов баз данных. Моя цель-снизить нагрузку на серверы, и я подумал, что один из способов-использовать потоковую передачу вместо загрузки огромных файлов в память

5. Потоковая передача загружает данные по частям, а не загружает все в память, поэтому при прочих равных условиях потоковая передача может иметь более низкое пиковое использование памяти. Но размер файла 2 МБ в этих измерениях практически является шумом (всего 2% кучи) и может быть компенсирован дополнительным использованием механизма потоковой передачи. Попробуйте сделать это с файлом объемом 2 ГБ, и разница станет гораздо более очевидной.