У меня есть значительные паузы для сбора мусора. Я хотел бы определить объекты, наиболее ответственные за эту коллекцию, прежде чем попытаюсь исправить эту проблему. Я посмотрел снимок кучи на Chrome, но (поправьте меня, если я ошибаюсь). Я не могу найти никакого индикатора того, что собирается, только то, что занимает больше всего памяти. Есть ли способ ответить на этот вопрос эмпирически, или я ограничена образованными догадками?
Как определить, какие объекты собираются сборщиком мусора?
Ответ 1
В хромовых профилях используются два снимка кучи, один перед выполнением действий, которые вы хотите проверить, и один за ним.
Теперь нажмите второй снимок.
В нижней строке вы увидите окно выбора с опцией "summary". Измените его на "сравнение".
Затем в поле выбора рядом с ним выберите моментальный снимок, который вы хотите сравнить (он должен автоматически выбрать моментальный снимок1).
В качестве результатов вы получите таблицу с данными, которые вам нужны, т.е. "Новые" и "Удаленные" объекты.
Ответ 2
С более новыми версиями Chrome появился новый инструмент, удобный для такого рода задач:
Тип профилирования "Record Heap Allocations". Обычный инструмент сравнения "Куча SnapShot" (как объясняется в ответах Rafał Łużyński) не может дать вам такую информацию, потому что каждый раз, когда вы делаете снимок кучи, выполняется GC-запуск, поэтому объекты GCed никогда не являются частью снимков. Однако с помощью инструмента "Запись кучи" всегда записываются все распределения (что может сильно замедлить ваше приложение во время записи). Если вы испытываете частые прогоны GC, этот инструмент может помочь вам определить места в вашем коде, где выделено много памяти. В сочетании с сравнением с кучей SnapShot вы увидите, что большую часть времени между двумя моментальными снимками выделяется намного больше, чем вы можете видеть из сравнения. В крайних случаях сравнение не даст никакой разницы, в то время как инструмент выделения покажет вам много и много выделенной памяти (которая, очевидно, должна была быть собрана мусором в то же время).
К сожалению, текущая версия инструмента не показывает вам, где было выделение, но покажет вам, что было выделено и как оно было сохранено во время выделения. Из данных (и, возможно, конструкторов) вы, однако, сможете идентифицировать свои объекты и, следовательно, место, где они выделяются.
Ответ 3
Если вы пытаетесь выбрать между несколькими вероятными преступниками, вы можете изменить определение объекта, чтобы привязать себя к глобальной области (как список под документом или что-то еще). Тогда это не позволит их собирать. Это может сделать программу быстрее (они не будут восстановлены) или медленнее (потому что они накапливаются и проверяются с помощью меток и разметки каждый раз). Поэтому, если вы видите изменение в производительности, возможно, вы обнаружили проблему.
Один из вариантов - посмотреть, сколько объектов создается для каждого типа (настроить счетчик в конструкторе). Если их собирают много, они также создаются так же часто.
Ответ 4
Взгляните на https://developers.google.com/chrome-developer-tools/docs/heap-profiling
особенно Containment View
Скрытый вид - это, по сути, "вид с высоты птичьего полета" вашего структура объектов приложения. Это позволяет вам заглянуть внутрь функции закрытия, чтобы наблюдать внутренние объекты VM, которые вместе составляют ваш JavaScript-объекты и понять, сколько памяти ваша заявка использует на очень низком уровне.
Вид содержит несколько точек входа:
Объекты DOMWindow - это объекты, которые рассматриваются как "глобальные" объекты для кода JavaScript; Корни GC - фактические корни GC, используемые мусором VM коллектор; Родные объекты - объекты браузера, которые "толкаются" внутри виртуальную машину JavaScript для автоматизации, например. Узлы DOM, Правила CSS (см. Следующий раздел для более подробной информации.) Ниже пример представления вида Containment: