Слабые ссылки и финализаторы (WeakRef)

Недавно в блоге V8 появилась статья, посвящённая новому пропозалу WeakRef (Stage 3) — "Weak references and finalizers".

Попробую объяснить своими словами его суть на примере. Представьте, что у вас в браузере происходит какая-то обработка изображений, например, на них накладывается водяной знак (согласен, пример не очень реалистичный), а затем эти изображения как-то используются. Водяной знак накладывается функцией, которая интенсивно потребляет CPU. Изображения могут повторяться, поэтому, чтобы лишний раз не загружать процессор, мы создаём кеш изображений с водяным знаком в Map, ключом пусть выступает название файла изображения. Но тут возникает проблема, если какое-то изображение не будет нами использоваться, оно всё равно будет находиться в памяти, так как Map по ключу будет на него ссылаться (strong reference). Поэтому, чтобы наш Map не отжирал лишнюю память, необходимо как-то определять такие ситуации и руками чистить кеш. Это не очень удобно.

Именно здесь на помощь приходит WeakRef. С помощью WeakRef можно создать слабую ссылку на изображение и записывать её по ключу вместо самого изображения:

const wr = new WeakRef(image);
cache.set(name, wr);
// для получения изображения
const ref = cache.get(name);
const image = ref.deref();

В этом случае сборщик мусора сможет самостоятельно определять ситуации, когда изображение в кеше уже не нужно и очищать память. Для очистки ключей из Map в пропозале предлагается использовать дополнительное API FinalizationGroup.

Интересный факт. В самом начале статьи даётся небольшой обзор уже входящих в стандарт WeakMap и WeakSet. Оказывается, что наиболее формальное название для отношения, которое используется в WeakMap — Ephemeron.

https://v8.dev/features/weak-references

← На главную