@Ivanushka255

Почему в WeakMap key и value не удаляются, когда выводишь всю коллекцию, но удаляются, когда при выводе одного эл-та?

1. Пример с "обнулением" value:
Почему в этом случае элемент все равно продолжает существовать в коллекции WeakMap?
let weakMap = new WeakMap();
let obj = {name: 'Ivan'};
//добавление нового элемента
weakMap.set({}, obj);
obj = null;
console.log(weakMap);
console.log(weakMap.get({}));

62ab5bc86affc580248729.png62ab5bceb7a7b289769773.png
2. Пример с "обнулением" key:
let weakMap = new WeakMap();
let obj = {name: 'Ivan'};
//добавление нового элемента
weakMap.set(obj, 255);
obj = null;
console.log(weakMap);
console.log(weakMap.get(obj));

62ab5bdd6cf06886582663.png
От чего это возникает? Сборщик мусора не успевает очистить все или как?
  • Вопрос задан
  • 89 просмотров
Пригласить эксперта
Ответы на вопрос 2
Seasle
@Seasle Куратор тега JavaScript
1. В WeakMap Вы положили ссылку на объект obj по литералу объекта. После того, как Вы заменили значение в obj, оно будет существовать в WeakMap, т.к. объект, по которому было записано значение не был удален или перезаписан. Ну и получить значение по новому литералу объекта не выйдет, т.к. они не равны между собой (ссылаются на различные участки памяти).
2. GC работает не мгновенно, с некоторой периодичностью. Можете его вызвать в Chrome DevTools: Ctrl+Shift+P -> Collect garbage.
Ответ написан
@GrayHorse
Первый пример некорректный, как уже написали. (Но рабочий.)

{name: 'Ivan'}

И что это еще за объект такой?

Вот это я понимаю объект new Uint8Array(100_000_000). Весомый.

Поспамь в консоль:
let weakMap = new WeakMap();
let obj = {a: new Uint8Array(100_000_000)};
weakMap.set({}, obj);


А теперь попробуй вместо WeakMap Map.

А для наглядности можно еще один нолик добавить: new Uint8Array(1_000_000_000).

Тестировать, например, тут: https://vueuse.org/core/usememory/#demo
Так так тут счетчик памяти наглядно показывает удаление объектов.

И, кстати, перезапись переменной let weakMap = new Map(); не поможет при таком спаме в консоль, т.к. если объект выведен в косколь, он так и будет висеть в памяти, пока консоль не будет очищена (console.clear()), либо страница перезагружена.

Второй пример корректный. Жать сюда: 62aba2885d1b5233390599.png

К слову, аналогичный класс из Java — WeakHashMap.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы