Принуждение сбора мусора в 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
Ответы
Ответ 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 никогда не падает? Обычно я держу вкладку открытой в течение нескольких недель за раз...