TGViewer
Настоящий JavaScript Настоящий JavaScript @true_js · 5.89K subscribers
Post #3576 360
Слабые ссылки и финализаторы: когда Rust не нужен, но GC бессилен

Управление памятью в JS — это иллюзия, пока не начнутся падения RSS в production. WeakRef и FinalizationRegistry — не инструменты для ежедневного кода, а спасение в сценариях, где классические паттерны утечек уже вылечены, а память продолжает расти. В production это актуально для long-running SPA, тяжёлых кэшей на Node.js и интеграций с нативными ресурсами вроде Canvas.

WeakRef: кэш, который убивает сам себя

Когда Map с картинками или JSON-ответами держит сильные ссылки — это утечка, если объект больше не нужен. WeakRef позволяет хранить ссылку, которую GC может забрать при нехватке памяти. Используйте для кэширования тяжёлых данных или слабых подписок в Observer-паттерне.

class SmartCache {
private data = new Map<string, WeakRef<object>>();

set(key: string, value: object) {
this.data.set(key, new WeakRef(value));
}

get(key: string): object | undefined {
return this.data.get(key)?.deref();
}
}


* Минус: .deref() может вернуть undefined в любой момент — обрабатывайте это явно.

FinalizationRegistry: cleanup для внешних ресурсов

Колбэк вызывается после сборки объекта. Нужен для освобождения WebSocket-соединений, файловых дескрипторов или памяти GPU. Не используйте для закрытия транзакций — колбэк может прийти с задержкой или не прийти до завершения процесса.

const registry = new FinalizationRegistry((id: string) => {
console.log(Cleanup: ${id});
});

class Heavy {
constructor(public id: string) {
registry.register(this, id);
}
}


* Типичная ошибка: делать в колбэке тяжёлую работу — V8 может зависнуть event loop.

Где без них реально не обойтись

* Long-running SPA с вкладками, которые не пересоздаются.
* Canvas/WebGL: ручное управление памятью — часть архитектуры.
* Node.js: кэши изображений или HLS-фрагментов в высоконагруженных сервисах.

Что ломается в production

* V8 реализует WeakRef с задержками — мгновенной очистки не ждите.
* FinalizationRegistry может вызвать колбэк не в том порядке.
* Это не замена грамотному управлению ссылками, а дополнительный слой для узких мест.

Как избежать боли

Напишите модуль-обёртку: внутри WeakRef и Registry, снаружи чистый API с fallback на пересоздание или ошибку. Разработчику не нужно знать о слабых ссылках. Тестируйте с помощью --expose-gc и следите за кучей в проде.

Вывод:
WeakRef — для кэшей и подписок, FinalizationRegistry — для внешних ресурсов, но оба требуют явной обработки исчезновения объекта и не отменяют необходимость профилирования памяти.
More from @true_js
  1. Oct 3, 2026Post #3963
  2. Oct 2, 2026😅 Айтишник отправил в одну компанию три одинаковых резюме и только одно дошло до финала О…
  3. Oct 2, 2026Post #3961
  4. Oct 2, 2026🤣 Правильно расставленные приоритеты в моей жизни би лайк: 💥 xCode Journal
  5. Oct 1, 2026🤯 Люди взбунтовались против «пыточной для ИИ» На GitHub заметили открытый проект AI Tortu…
  6. Oct 1, 2026День в Заонежье начинается ещё в дороге. Мы встретим вас в аэропорту или на вокзале. Дальш…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →