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

Принуждение сбора мусора в Google Chrome

Мы разрабатываем одностраничное веб-приложение с ZK, которое постоянно общается с сервером и обновляет части своих экраны. Обновление может быть таким же частым, как 1 с. Во время этих обновлений теряются ссылки на большие количества объектов JS, и в конечном итоге эти объекты должны быть очищены сборщиком мусора.

Насколько мы поняли, Chrome только запускает сборщик мусора на неактивных вкладках. Это проблема для нас, потому что вкладка приложения обычно активна и почти никогда не обновляется, поэтому объекты JS никогда не собираются. Если вы остаетесь активным в течение достаточного времени, вкладка в конечном счете выйдет из строя (сообщение All Snap).

Нам нужно инициировать сборку мусора вручную. До сих пор мы пытались запустить Chrome с помощью --js-flags="--expose-gc" и запускать gc(), но он выдает исключение:

ReferenceError: gc is not defined

Этого не происходит в Firefox - использование памяти более или менее постоянное.

Повторное обновление страницы не является параметром.

Мы будем благодарны за любые предложения.

EDIT: мы попытались запустить window.gc() и gc() как в версиях Chrome 23.0.1271.97 m, так и 25.0.1364.2 dev-m

4b9b3361

Ответ 1

Вы можете извлечь код из инструментов Chrome Dev Tools, изменить его так, чтобы время от времени вызывается ProfilerAgent.collectGarbage(); (это код, который вызывается при нажатии кнопки "Собрать мусор" на панели временной шкалы) и запускайте Chrome с помощью версии DevTools с использованием флага --debug-devtools-frontend.

Однако это решение довольно экстремально, попробуйте его только тогда, когда вы действительно отчаялись. До этого я предлагаю профилировать ваше приложение и проверять, почему v8 решает не очищать мусор (или не может очистить мусор). Панель Timeline DevTools поможет вам в этом. Начните с проверки, если кнопка "Собирать мусор" внизу этой панели действительно выполняет свою работу, если нет - у вас, вероятно, есть утечка памяти (по крайней мере, согласно версии 8). Если да, попробуйте leak-finder-for-javascript.

[ EDIT] Я удалил информацию о расширении chrome, так как оказывается, что gc() можно вызывать из кода веб-страницы, когда используется --js-flags="--expose-gc". По крайней мере, на моем 23.0.1271.64.

Ответ 2

В Chrome Developer Tools у вас есть раздел "Хронология", начиная с Chrome 53. У вас там кнопка выглядит как Мусорная корзина. щелкнув по нему, он принудительно запускает сборщик мусора. enter image description here

Обновить:

Кнопка GC переместилась на вкладку Performance в более поздних версиях Chrome. enter image description here

Ответ 3

Я нашел решение. По-видимому, Chrome теряет узлы DOM, по крайней мере, в текущей версии (26.0.1410.65 прямо сейчас)

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

Я попробовал последнюю версию Chrome Canary (28.0.1500.3), и они, похоже, исправили эту проблему. DOM Node граф подсчета теперь следует тем же ритмическим рисунком, что и слушатели событий.

То, что меня достает, - это... почему Gmail никогда не падает? Обычно я держу вкладку открытой в течение нескольких недель за раз...