Подтвердить что ты не робот

Могу ли я запускать сборку мусора JavaScript?

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

4b9b3361

Ответ 1

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

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

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

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

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

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

    Bertil [Массив объектов] → Joshua [Объект] → Smith [Массив байтов] → Безымянный [Байт].

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

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

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

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

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

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

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

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

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

Ответ 2

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

Internet Explorer:

window.CollectGarbage()

Opera 7 +:

window.opera.collect()

Ответ 3

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

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

Насколько я знаю, нет возможности вручную запускать сборку мусора.

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

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

Если вам нужно прочитать на Factory Шаблоны, то возьмите себе эту книгу "Шаблоны дизайна Javascript" Росса Хармеса и Дастина Диаса и опубликованы APress.

Ответ 7

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

1) var wm = new WeakMap()

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

3) wm.set(d, {})

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

4) d = null

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

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

Ответ 8

Я читал ответ Тревор Прайм, и это дало мне хихиканье, но потом я понял, что он что-то придумал.

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

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

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

Ответ 9

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

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

ДОБАВЛЕНО:

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