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

Имеет ли смысл пытаться помочь сборщику мусора JavaScript?

Поскольку я более активно использую JavaScript, как высокоуровневый объектно-ориентированный язык, я считаю себя похожим на программиста на C/С++, которым я являюсь, когда я заканчиваю объекты. Я знаю, что GC собирается бежать в конце концов и очистить мой беспорядок, но есть ли что-то, что я могу сделать, чтобы на самом деле помочь ему?

Например, у меня есть массив больших/сложных первичных объектов... каждый первичный объект может иметь массивы и другие вспомогательные ссылки на объекты внутри. Если я закончил с основным объектом и просто удалю его из массива, GC, вероятно, в конечном итоге выяснит все остальное, что объект указал на все сам по себе, круговые внутренние ссылки и все. Но имеет ли смысл удаление основного объекта из массива хранения, чтобы пройти через него, и array.length = 0 любые массивы и reference = null любые объекты, чтобы упростить задачу GC (например, явное удаление ссылок означает меньше для GC трек)? Вид ручного деструктора, если хотите. Стоит ли это делать или я трачу время/усилия на малое/отсутствие выигрыша?

Я полагаю, что это скорее общая теория вопроса GC (Java и т.д.), но в первую очередь меня интересует JavaScript для целей этого вопроса.

Спасибо!

4b9b3361

Ответ 1

Это может зависеть от конкретного сборщика мусора, поэтому ответ будет зависеть от того, какой механизм JavaScript вы используете.

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

С учетом сказанного, в соответствии с заметками Google на V8, которые являются механизмом JavaScript, используемым Chrome,

V8 восстанавливает память, используемую объектами, которые больше не требуются в процесс, известный как сбор мусора. Чтобы обеспечить быстрое распределение объектов, короткая сборка мусора, пауза и отсутствие фрагментации памяти V8 использует стоп-мир, поколение, точный сборщик мусора. Это означает, что V8:

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

В V8 куча объекта разделена на две части: новое пространство, где объекты и старое пространство, в которое поощряется цикл сбора мусора. Если объект перемещается в цикл сбора мусора, V8 обновляет все указатели на объект.

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

В качестве примера поведения хорошо документированной реализации GC, Java Concurrent Mark-Sweep collector:

  • Останавливает приложение.
  • Создает список объектов, доступных из кода приложения.
  • Восстанавливает приложение. Параллельно сборщик CMS запускает фазу "отметки", в которой он отмечает транзитно достижимые объекты как "не мусор". Поскольку это параллельно с выполнением программы, оно также отслеживает изменения ссылок, сделанные приложением.
  • Останавливает приложение.
  • Запускает вторую ( "замечательную" ) фазу для отметки новых достижимых объектов.
  • Восстанавливает приложение. Параллельно он "зачищает" все объекты, идентифицированные как мусор, и восстанавливает блоки кучи.

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

Там хорошая, хотя и несколько устаревшая, белая статья о том, как сборка мусора Java работает на http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf. Сбор мусора не уникален для Java, поэтому я подозреваю некоторое сходство между различными подходами, используемыми виртуальными машинами Java и другими средами выполнения, такими как движки JavaScript.

Раймонд Чен написал сообщение в блоге, в котором указывалось, что ходячая память, которую вы собираетесь освободить, может отрицательно повлиять на производительность. Контекст заключался в том, чтобы освободить память вручную при завершении работы приложения. Поскольку блоки могли быть заменены на диск, действие перемещения ссылок может привести к замене этих блоков. В этом случае программа выполняет обход блоков, которые только что были помечены как доступные и оставленные нетронутыми.

Таким образом, в ситуации, когда ОС, возможно, заменила некоторые блоки, действие "оказания помощи" сборщику мусора, особенно на более долгоживущих объектах, может привести к замедлению работы.

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

Таким образом, это не стоит усилий и может быть контрпродуктивным. Хотя, вероятно, имеет смысл отбросить ссылки на кучи "доминанты". Это объекты, которые, если они будут собраны, позволят собирать многие другие объекты. Поэтому оставьте ссылку на саму коллекцию, но не на каждый элемент коллекции.

Ответ 2

Редко.

Это не так, как никогда.

Как правило, если вы разрабатываете разумным образом, неиспользуемые объекты будут выходить за пределы области действия, и сборщик мусора будет работать так, как ожидалось. И если вы действительно не понимаете, что делаете, усилия, направленные на то, чтобы помочь сборщику мусора выполнять свою работу, часто не работают должным образом. Мусорная коллекция - это область, которая претерпела существенную оптимизацию со стороны создателей различных движков Javascript. Как правило, вы не должны с ним связываться, если:

  • У вас доказано для себя, с жесткими цифрами из инструментов анализа, которые есть реальная потребность и
  • Вы можете продемонстрировать реальное понимание того, что на самом деле должно быть изменено, чтобы чтобы помочь сборщику мусора.

Ничего из этого легко достичь.

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

Ответ 3

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

Если сбор мусора становится для вас значительной издержкой, вам, скорее всего, лучше сосредоточиться на сокращении количества объектов, которые нужно собрать мусором (подумайте Шаблон пула объектов)