Я хочу, чтобы вызвать сборку мусора JavaScript. Является ли это возможным? Почему я хочу или не хочу делать это?

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

Люди по всему городу говорят, что удаление ссылок поможет. Некоторые люди говорят, что стирание объекта является дополнительной гарантией ( пример ). Поэтому я написал скрипт, который попробует все приемы в книге, и был удивлен, увидев, что в Chrome (22.0.1229.79) и IE (9.0.8112.16421) сборка мусора даже не работает. Firefox (15.0.1) обходился без каких-либо серьезных недостатков, кроме одного (см. Пример 4f ниже).

В псевдокоде тест проходит примерно так.

  1. Создайте контейнер, массив, который будет содержать объекты некоторого вида. Мы назовем этот контейнер Bertil здесь.

  2. Каждый объект в нем, как элемент в Bertil, должен иметь свой собственный массив-контейнер, объявленный как свойство. Этот массив будет содержать много байтов. Мы назовем любой из элементов Бертиля, объект , Joshua . Каждый байтовый массив Иисуса Навина будет называться Smith .

    Вот карта ума, на которой вы можете откинуться:

    Bertil [Массив объектов] -{amp}gt; Joshua [Объект] -{amp}gt; Smith [Массив байтов] -{amp}gt; Безымянный [Байт].

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

    4а. Бросить операнд удаления в контейнер основного объекта, Bertil.

    4b. Бросьте операнд удаления на каждый объект в этом контейнере, убейте каждого Джошуа живым.

    4c. Бросить операнд удаления на каждый массив байтов Смитов.

    4d. Назначьте NULL каждому Иисусу.

    4e. Назначьте НЕ УКАЗАН каждому Джошуа.

    4f. Вручную удалите каждый байт, который есть у любого Иисуса Навина.

    4g. Сделайте все вышеперечисленное в рабочем порядке.

Итак, что случилось? В случаях 4a и 4b ни один сборщик мусора (GC) браузера не включился . В случае 4c-4e Firefox включился и продемонстрировал некоторое подтверждение концепции. Память была восстановлена ​​в ближайшее время в течение минуты. С текущими жестко заданными значениями по умолчанию для некоторых переменных, используемых в качестве тестовой конфигурации, случаи 4f и 4e привели к зависанию Chrome, поэтому я не могу сделать никаких выводов. Вы можете проводить собственное тестирование со своими переменными, ссылки будут опубликованы в ближайшее время. IE выжил в случаях 4f и 4e, но его сборщик мертв, как обычно. Неожиданно Firefox выжил, но не прошел 4f. Firefox выжил и прошел 4g.

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

Мой вывод таков: я, должно быть, допустил ужасную ошибку в коде, или ответ на ваш вопрос: нет, мы не можем вызвать GC. Всякий раз, когда мы пытаемся это сделать, мы будем сурово наказаны, и мы должны сунуть головы в песок. Пожалуйста, я призываю вас идти вперед, попробуйте эти тестовые примеры самостоятельно. Посмотрите в коде были комментарии к деталям. Кроме того, загрузите страницу и перепишите скрипт и посмотрите, сможете ли вы активировать GC более корректным способом. Я уверен, что потерпел неудачу, и я не могу поверить, что в Chrome и IE нет работающего сборщика мусора.

http://martinandersson.com/dev/gc_test/?case=1

http://martinandersson.com/dev/gc_test/?case=2

http://martinandersson.com/dev/gc_test/?case=3

http://martinandersson.com/dev/gc_test/?case=4

http://martinandersson.com/dev/gc_test/?case=5

http://martinandersson.com/dev/gc_test/?case=6

http://martinandersson.com/dev/gc_test/?case=7

Вы можете вручную запустить сборщик мусора JavaScript в IE и Opera, но это не рекомендуется, так что лучше вообще его не использовать. Я даю команды больше только для информационных целей.

Internet Explorer:

 window.CollectGarbage() 

Опера 7 :

 window.opera.collect() 

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

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

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

  1. Проверьте свой код на наличие глобальных переменных. Могут быть данные, поступающие через вызов ajax, которые сохраняются, а затем куда-то ссылаются, и вы не приняли это во внимание.
  2. В качестве решения вы должны заключить обработку огромных данных в анонимный вызов функции и использовать внутри этого вызова только локальные переменные, чтобы предотвратить обращение к данным в глобальной области.
  3. Или вы можете присвоить нулю все используемые глобальные переменные.
  4. Также проверьте этот вопрос . Взгляните на третий пример в ответе. На ваш огромный объект данных все еще может ссылаться закрытие асинхронного вызова.

В этом ответе предлагается следующий код запроса сборки мусора для браузеров на базе Gecko:

  window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils) .garbageCollect(); 

Да, вы можете запустить сборку мусора, перезагрузив страницу.

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

Если вам нужно почитать о Factory Patterns, приобретите эту книгу «Pro Javascript Design Patterns» Росса Хармеса и Дастина Диаса, изданную APress.

Наткнулся на этот вопрос и решил поделиться с моими недавними выводами. Я посмотрел, чтобы увидеть правильную обработку WeakMap в Chrome, и это на самом деле выглядит хорошо:

1) var wm = new WeakMap()

2) var d = document.createElement('div')

3) wm.set(d, {})

на этом этапе слабая карта содержит входную причину, поскольку d все еще ссылается на элемент

4) d = null

на этом этапе ничто не ссылается на элемент и на объект со слабой ссылкой, и действительно, через пару минут запись исчезла и сборщик мусора.

когда сделал то же самое, но добавил элемент в DOM, он не был возвращен, что правильно, удален из DOM и все еще ждет его сбора :)

Я читал ответ Тревора Прайма, и он рассмеялся, но потом я понял, что он что-то замышляет.

  1. Перезагрузка страницы делает сборщик мусора.
  2. location.reload () или альтернативы для обновления страницы.
  3. JSON.parse / stringify и localStorage.getItem / setItem для сохранения необходимых данных.
  4. iframes как перезагрузка страниц для удобства пользователей.

Все, что вам нужно сделать, это запустить ваш код в iframe и обновить страницу iframe, сохраняя при этом полезную информацию в localStorage. Вы должны убедиться, что iframe находится в том же домене, что и главная страница, чтобы получить доступ к его DOM.

Вы можете сделать это без iframe, но опыт пользователя, несомненно, пострадает, так как страница будет заметно сбрасываться.

Если это правда, что нет никакого способа запустить GC, как подразумевается в других ответах, то решение было бы для соответствующей группы стандартов браузера добавить новую функцию JavaScript в окно или документ, чтобы сделать это. Полезно разрешить веб-странице запускать GC в любой момент по своему выбору, чтобы анимация и другие высокоприоритетные операции (вывод звука?) Не прерывались GC.

Это может быть еще один случай синдрома «мы всегда так делали; не раскачивай лодку».

ДОБАВЛЕНО:

MDN документирует функцию «Components.utils.schedulePreciseGC», которая позволяет странице планировать GC когда-нибудь в будущем с помощью функции обратного вызова, которая вызывается, когда GC завершается. Это может не существовать в других браузерах, кроме Firefox; документация неясна. Эта функция может быть использована до анимации; это должно быть проверено.