На этой неделе Шо и я провели презентацию концепции замыкания в JavaScript на Flatiron School Presents. Проводя исследование, мы столкнулись с одним недостатком использования замыканий: утечками памяти.

Утечка памяти происходит, когда программа запрашивает и занимает память, но фактически не использует ее. Компьютерная память хранится и извлекается из оперативной памяти (ОЗУ) точно так же, как краткосрочная память человека хранится в гиппокампе, очень специфической области нашего мозга. Память, которую временно хранит оперативная память, — это данные запущенных приложений.

К счастью, JavaScript — это язык «сборки мусора», который автоматически освобождает объекты и строки, которые больше не используются. Поэтому локальные переменные в функции освобождаются, когда функция их возвращает, и освобождает место для выделения другой памяти.

Но что, если функция является замыканием?

Чтобы дать понимание утечек памяти в JavaScript, я хотел бы указать на наиболее заметный атрибут замыкания. Тем не менее, я не буду вдаваться в концепцию закрытия в этом посте, так как само закрытие является огромной темой для обсуждения.

Замыкание — это дочерняя (внутренняя) функция, которая имеет доступ к области видимости своих родительских (внешних) функций. Чтобы быть более ясным, замыкания в JavaScript могут получить доступ к информации во внешних функциях, потому что они несут ссылки на переменные внешних функций, а не на фактическое значение. Например, если значение переменной y изменится с 15 на 5, функция g() сохранит обновленное значение 5.

Поскольку задача замыкания состоит в том, чтобы удерживать ссылку на область действия внешней функции, а не освобождаться, она занимает дополнительное место в оперативной памяти в вашей системе. Это явление очень похоже на определение утечек памяти, не так ли?

Это всего лишь один пример различных потенциальных причин утечек памяти в вашей системе. Другие причины, связанные с JavaScript, могут включать следующее:

  1. Использование таймеров или обратных вызовов, которые ссылаются на данные, которые больше не требуются
  2. Не удалять явно EventListeners, когда они не нужны за пределами локальной области

Чтобы проверить, сколько места в памяти занимают запущенные в данный момент приложения, вы можете найти Spotlight Search «Мониторинг активности» и щелкнуть вкладку «Память».

В этом конкретном примере у меня было открыто около 29 вкладок в Chrome с некоторыми другими приложениями. Монитор активности показывает, что все, что я делаю на своем компьютере в данный момент, занимает 7,01 ГБ / 8,00 ГБ ОЗУ.

Когда ОЗУ заполнено, содержимое сохраняется на жесткий диск, чтобы освободить место в ОЗУ. Этот процесс называется «обмен». В приведенном выше примере 227 МБ моего ОЗУ были заменены таким же объемом на моем жестком диске. Хотя доступ к данным, хранящимся в оперативной памяти, может быть мгновенным, для извлечения данных с жесткого диска требуется больше времени. В отличие от оперативной памяти, которая временно хранит данные, данные на диске сначала необходимо найти, прочитать и отправить в оперативную память, прежде чем они будут обработаны.

Итак, как узнать, есть ли утечка памяти? Утечки памяти не приводят к физическому или необратимому повреждению. Поскольку это проблема программного обеспечения, это замедлит работу приложений или даже всей вашей системы. Однако программа, занимающая много места в оперативной памяти, не всегда означает, что ее память куда-то утекает. Программе, которую вы используете, может действительно понадобиться столько места.

Ранее в посте я упомянул, что JavaScript — это язык сборки мусора. Сборка мусора запускается, когда память выделяется и теряется. Он ищет память, которая не используется, и возвращает ее системе, уменьшая вероятность утечек памяти (которые не вызваны замыканиями!)

Узнайте больше об использовании инструментов разработчика для обнаружения утечек памяти: