В Предыдущем блоге мы разобрались с управлением памятью в Node.js, как работает сборщик мусора (GC) и каковы возможные причины утечек памяти, несмотря на то, что GC играет решающую роль. В этом блоге давайте рассмотрим лучшие практики для обеспечения эффективного использования памяти в Node.js.

СОКРАЩЕНИЕ ИСПОЛЬЗОВАНИЯ ГЛОБАЛЬНЫХ ПЕРЕМЕННЫХ

Поскольку глобальные переменные никогда не удаляются сборщиком мусора, лучше не злоупотреблять ими.

В частности, в javascript вам нужно помнить об определенных аспектах, чтобы уменьшить глобальные переменные.

  1. Избегайте случайных глобальных переменных

В Javascript, если вы присваиваете значение необъявленной переменной, Javascript автоматически поднимает ее как глобальную переменную в режиме по умолчанию. Кроме того, то же самое относится и к слову this, используемому в функциях в глобальной области видимости.

Примеры:

function apple() {
	red = true; // this red variable gets hoisted in global space
}
function mango() {
// since 'this' in global functions refers to global this varible is hoisted in global space
this.type = "Alphanso";  
}

Решение. Полезно писать javascript в строгом режиме с аннотацией «использовать строгий» в верхней части JS-файла. В более новых версиях Node.js вы можете глобально включить строгий режим, передав флаг ‘—use_strict’ ​​при выполнении команды node.

'use strict'
function apple() {
	red = true; // this will throw an error
}
function mango() {
// this function will have its own scope for 'this'
this.type = "Alphanso";  
}

Внимание! Будьте осторожны при использовании стрелочных функций, потому что даже в строгом режиме использования "это" в стрелочной функции будет в глобальном пространстве.

// This will also become a global variable as arrow functions
const plantation = () => {
    this.coconut = "Brown";
}

решение: используйте правило no-invalid-this от ESLint, чтобы избежать таких случаев.

Используйте глобальную область разумно:

  • Насколько это возможно, не используйте глобальную область видимости, максимально используйте локальную область видимости внутри функций, так как это будет собирать мусор и освобождать память.
  • Попробуйте определить только константы, кеш и повторно используемые переменные в global. Отметьте переменные как нулевые, когда значения не нужны.
  • Не используйте глобальное пространство в качестве среды для передачи значений из одной функции в другую, вместо этого используйте параметры функции.
  • Не храните большие объекты в глобальной области видимости. Если вам нужно их сохранить, то аннулируйте их, когда они не нужны. Не позволяйте объектам кеша расти бесконечно, очищайте время от времени.

2. Эффективно используйте память стека

Доступ к стеку намного быстрее, чем доступ к памяти кучи, поэтому старайтесь использовать переменные стека чаще, чем их аналоги. Это также гарантирует, что мы случайно не вызовем утечки памяти. Конечно, в реальном сценарии невозможно создать пригодное для использования приложение, используя только статические данные. Но мы можем воспользоваться некоторыми приемами, чтобы лучше использовать стек.

  1. По возможности избегайте ссылок на объекты кучи из переменных стека. Кроме того, не оставляйте неиспользуемые переменные.
  2. Деструктурируйте и используйте поля, необходимые для объекта или массива, вместо того, чтобы передавать целые объекты/массивы функциям. Это позволяет избежать сохранения ссылок на объекты внутри замыканий.
function outer() {
    const obj = {
        foo: 1,
        bar: "hello",
    };
const closure = () {
        const { foo } = obj;
        myFunc(foo);
    }
}
function myFunc(foo) {}

3. Эффективно используйте динамическую память

В реальных приложениях совершенно невозможно полностью избежать использования динамической памяти, но мы можем сделать ее более эффективной, следуя нескольким советам:

  1. копировать объекты вместо ссылки на них. Передавайте ссылку только в том случае, если объект огромен, а операция копирования требует больших затрат.
  2. По возможности избегайте мутаций объектов, вместо этого используйте распространение объектов или object.assign и создайте копию.
  3. Избегайте создания нескольких ссылок на один и тот же объект
  4. Избегайте создания огромных деревьев объектов, иначе они будут недолговечными.

4. Будьте осторожны при использовании замыканий, таймеров и обработчиков событий

Для таймеров всегда не забывайте передавать копии объектов, чтобы избежать мутаций и очищать таймеры, когда это делается с помощью методов clearTimeout и clearInterval.

Кроме того, очищайте слушателей после завершения работы, не оставляйте их включенными навсегда. В тех случаях, когда они держат ссылку на объект из родительской области.

первоначально опубликовано на amodshinde.com