Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Java heap overhead, memory leaks / 25 сообщений из 26, страница 1 из 2
06.12.2016, 16:04
    #39361331
publexus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
Работает приложение на GlassFish 4.1, jdk1.8.0_77.

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

Такое ощущение, что GC просто перестает собирать мусор. В логе было сообщение GC overhead limit. Я отключил лимиты опцией -XX:-UseGCOverheadLimit - та же ситуация, но в логе glassfish теперь вообще никаких ошибок нет. Если успеть отловить момент роста и вручную через VisualVM запустить GC, то память очищается и приложение продолжает нормально работать (до очередного глюка, естественно).

Делал heap dump в момент нормальной работы, львиную часть памяти занимают HashMap$Node. После переполнения снять дамп не удается - VisualVM подвисает. Недолго живущие Hashmap'ы используются в программе десятками тысяч, но и оперативки выделено 16 Гб, и при нормальном режиме (как видно на картинке) памяти используется в среднем около 1.5 ГБ.

Что происходит? И как заставить GC принудительно выполнять полную очистку с определенным периодом (если это поможет)?
...
Рейтинг: 0 / 0
06.12.2016, 16:12
    #39361342
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
Какой тип сборщика? Какие размеры поколений? Про VisualVM пишут что он с большими кучами никак не справляется. Для анализа больших куч желательно иметь платный профайлер под рукой. Другое дело что ещё нужно и дамп как-то снять.
Настройте и читайте GC Log в продакшне. Напишите триггер, который бы пробовал сделать дамп не на 16Gb, а на 4-8, при условии что 1,5Gb - нормальная загрузка.

Сопаставьте время в GC Log-е с логом приложения и посмотрите что же реально происходит в момент стремительного роста.
...
Рейтинг: 0 / 0
06.12.2016, 16:40
    #39361369
publexus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
Еще картинка из VisualVM в добавление к предыдущей:
...
Рейтинг: 0 / 0
06.12.2016, 16:41
    #39361370
publexus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
Параметры
...
Рейтинг: 0 / 0
06.12.2016, 16:47
    #39361377
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
Eden я бы сделал побольше.
...
Рейтинг: 0 / 0
06.12.2016, 16:54
    #39361382
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusПараметры
MaxPermSize у вас не работает, так как у вас Metaspace вместо него.
Отключать GCOverheadLimit это всё равно что бороться с пожаром путём отключения пожарной сигнализации.
Тут немного про young. Хотя дело не в нём.
https://blogs.oracle.com/jonthecollector/entry/the_second_most_important_gc

Есть какие-то асинхронные процессы в приложении?
...
Рейтинг: 0 / 0
06.12.2016, 16:58
    #39361387
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusЧто происходит? И как заставить GC принудительно выполнять полную очистку с определенным периодом (если это поможет)?
попробуй анализ кода на закрытие ресурсов в коде. У меня помогло. Правда смотрел сам глазами)).
...
Рейтинг: 0 / 0
06.12.2016, 17:01
    #39361390
publexus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
Blazkowicz,

Да, асинхронные процессы есть: по запросу пользователя может запускаться несколько потоков, каждый из которых может оперировать своим (неразделяемым) набором hashmaps. Но в момент роста памяти кардинальных отклонений от стандартного режима нет.
...
Рейтинг: 0 / 0
06.12.2016, 17:03
    #39361395
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusПараметрыЗадлянафига гигантская разбежка между минимальным и максимальным размером кучи?
Сделайте одинаково и, как уже советовали ~3-4Гб.
...
Рейтинг: 0 / 0
06.12.2016, 17:03
    #39361396
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusИ как заставить GC принудительно выполнять полную очистку с определенным периодом (если это поможет)?
Это вообще никак не поможет. Есть молодое поколение - там сборка происходит часто в фоновом режиме и без каких либо телодвижений. Есть старое поколение - там сборка происходит редко, потому что сборка в старом поколении включает Stop-the-world фазы, который для многопользовательского сервера очень вредны.
У вас старое поколение забивается под завязку и многократный вызов GC ничего не освобождает. Так что насильный вызов вряд ли приведёт к другому результату.
...
Рейтинг: 0 / 0
06.12.2016, 17:06
    #39361398
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusДа, асинхронные процессы есть: по запросу пользователя может запускаться несколько потоков, каждый из которых может оперировать своим (неразделяемым) набором hashmaps. Но в момент роста памяти кардинальных отклонений от стандартного режима нет.
Ну, я имел ввиду что-то типа RxJava. С такими решениями есть классический косяк, когда событие уходит в цикл между разными потоками, а каждый вызов создаёт кучу объектов. Единственное что странно, что у вас эти данные где-то в глобальном хранилище оседают. Судя по графику они почти сразу в tenured улетают и в Eden особо не задерживаются.
...
Рейтинг: 0 / 0
06.12.2016, 18:45
    #39361464
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusТакое ощущение, что GC просто перестает собирать мусор.

Что происходит? И как заставить GC принудительно выполнять полную очистку с определенным периодом (если это поможет)?
Еслиб он перестал - то оранжевенького над сининьким не было бы. А так - есть.
Делать dump. Находить машину с бOльшим количеством памяти (чем ваши 16). Загружать в профайлер (в VisualVM не соглашаться на полный анализ - надоест ждать). И смотреть что стало отъедать память.

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

Например в Котяре как-то стали сессии на websocket запросах виснуть. Новые переоткрывались. А старые за собой тянули все и не отпускали. Смотреть надо, чем прирастает и какой gc_root держит.
...
Рейтинг: 0 / 0
06.12.2016, 20:18
    #39361498
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
Вы обычные мапы используете или какую-то разновидность по типу Weak\Soft? Есть ли места, где создаются большие массивы, которые могут не влезть в Eden? Размер стэка у потоков дефолтный?
...
Рейтинг: 0 / 0
07.12.2016, 11:37
    #39361673
publexus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
забыл никВы обычные мапы используете или какую-то разновидность по типу Weak\Soft? Есть ли места, где создаются большие массивы, которые могут не влезть в Eden? Размер стэка у потоков дефолтный?


Настройки стека не трогал.
В вычислениях используются обычные HashMap, которых по моим подсчетам должно создаваться максимум несколько тысяч одновременно.
Также довольно интенсивно используются списки мапы возвращаемые spring JdbcTemplate, которые без изменений далее передаются на отображение в primefaces datable. Таких, по моим подсчетам, одновременно может создаваться несколько десятков тысяч. Но их намного больше, как показывает картинка, которая снята в момент обычной активности, при использовании памяти в районе 2ГБ.
...
Рейтинг: 0 / 0
07.12.2016, 11:41
    #39361679
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusВ вычислениях используются обычные HashMap, которых по моим подсчетам должно создаваться максимум несколько тысяч одновременно.
Заведите глобальный счетчик, и логируйте его. Тогда будет понятно косяк в этом коде или где-то ещё. Не удивлюсь если ваша ситуация вообще сюрприз от GlassFish.
...
Рейтинг: 0 / 0
07.12.2016, 14:20
    #39361827
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusВ вычислениях используются обычные HashMap, которых по моим подсчетам должно создаваться максимум несколько тысяч одновременно.
А как часто они по Вашему должны исчезать?
Тем юолее, что их у Вас не так уж и много -74 тысячи.
В принципе, можно и сейчас посмотреть на корни, которые их держат.
Но интереснее IMHO - там на картинке буковки Сompare.
И именно тогда, когда начинается рост.
Ловля блох в момент нормальной работы может быть никак не связана с причиной лавионообразного роста.

Может Вас вообще кто хакает и начинает утягивать базу в виде одного большого XML. :)
...
Рейтинг: 0 / 0
07.12.2016, 14:43
    #39361857
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusТакже довольно интенсивно используются списки мапы возвращаемые spring JdbcTemplate
вы работает с БД?
Тогда почему нет ни слова про БД? Про закрытие соединения или возврат в пул? Про нагрузку и статистику со стороны БД?
У вас просто драйвер JDBC может съесть всю память при некорректном коде.
IMHO
...
Рейтинг: 0 / 0
07.12.2016, 16:26
    #39361965
publexus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
Petro123publexusТакже довольно интенсивно используются списки мапы возвращаемые spring JdbcTemplate
вы работает с БД?
Тогда почему нет ни слова про БД? Про закрытие соединения или возврат в пул? Про нагрузку и статистику со стороны БД?
У вас просто драйвер JDBC может съесть всю память при некорректном коде.
IMHO


Для соединения к БД использую Hicari, настроенный как бин, который передаю JdbcTemplate и использую исключительно его для доступа к БД. Там, как мне кажется придраться не к чему. Соединения к базе и активность в ней я анализировал, там ничего особенного не было.
...
Рейтинг: 0 / 0
07.12.2016, 16:39
    #39361986
publexus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
Сергей АрсеньевpublexusВ вычислениях используются обычные HashMap, которых по моим подсчетам должно создаваться максимум несколько тысяч одновременно.
А как часто они по Вашему должны исчезать?
Тем юолее, что их у Вас не так уж и много -74 тысячи.
В принципе, можно и сейчас посмотреть на корни, которые их держат.
Но интереснее IMHO - там на картинке буковки Сompare.
И именно тогда, когда начинается рост.
Ловля блох в момент нормальной работы может быть никак не связана с причиной лавионообразного роста.

Может Вас вообще кто хакает и начинает утягивать базу в виде одного большого XML. :)

В том то и дело, что я не могу сравнить или посмотреть что там в памяти аномального сидит.

Как я писал выше, если в момент роста памяти в VisualVM включить мусорщик принудительно, то память очищается практически полностью (мегабайт до 200-300), аномальный рост памяти обрывается и приложение функционирует нормально.

Если я выполняю Heap dump, то перед снятием снимка памяти также почему-то происходит запуск мусорщика и память тоже очищается. Если же память переполнилась, то процесс jvm просто подвисает - не реагирует ни на какие запросы, asadmin не отвечает, помогает только kill -9. Если VisualVM была подключена к jvm, то спустя некоторое время после переполнения тоже отключается от нее. Естественно, снять дапм в этом случае тоже не получается.

Т.е. я никак не могу получить информацию о том, что же там растет.
...
Рейтинг: 0 / 0
07.12.2016, 17:09
    #39362010
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusТам, как мне кажется придраться не к чему. Соединения к базе и активность в ней я анализировал, там ничего особенного не было.
ну если вы так уверены). То и разговора нет.
Т.к. банальное отсутствие
(recordSet\Statement\...).Close
даст утечку памяти.
Удачи!
...
Рейтинг: 0 / 0
07.12.2016, 17:31
    #39362023
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusВ том то и дело, что я не могу сравнить или посмотреть что там в памяти аномального сидит.

Как я писал выше, если в момент роста памяти в VisualVM включить мусорщик принудительно, то память очищается практически полностью (мегабайт до 200-300), аномальный рост памяти обрывается и приложение функционирует нормально.

Если я выполняю Heap dump, то перед снятием снимка памяти также почему-то происходит запуск мусорщика и память тоже очищается. Если же память переполнилась, то процесс jvm просто подвисает - не реагирует ни на какие запросы, asadmin не отвечает, помогает только kill -9. Если VisualVM была подключена к jvm, то спустя некоторое время после переполнения тоже отключается от нее. Естественно, снять дапм в этом случае тоже не получается.

Т.е. я никак не могу получить информацию о том, что же там растет.
Есть подозрение что вы немного заблуждаетесь. Если у вас JVM уже "зависла", это значит что уже работает самая полная сборка с остановкой всех других потоков. А UseGCOverheadLimit выкидывает вам исключение когда ещё не "всё потеряно", но полная сборка мусора уже не приносит особых результатов. Так вот VisualVM запускает точно такую же полную сборку. И быть того не может чтобы она собрала то с чем не справился сборщик в штатном режиме.

Более детально можно понять читая GC Log. Если у вас проблема регулярная, то совершенно не понятно почему вы до сих пор его не включили и не опубликовали.

Совсем не сложно написать JMX монитор кучи, который бы вызывал дамп при подозрительном росте, раньше чем вы это сделаете вручную в VisualVM. Плюс вы там можете залогировать любое своё состояние - количество пользователей, размеры текущих сессий и т.п.

Ну, и не забывайте про чтение манулов
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/toc.html
Если уж вы добрались до VisualVM, то должны и работу GC осилить.
...
Рейтинг: 0 / 0
07.12.2016, 17:32
    #39362024
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
Petro123ну если вы так уверены). То и разговора нет.
Т.к. банальное отсутствие
(recordSet\Statement\...).Close
даст утечку памяти.
Удачи!
Тут не совсем обычная утечка. Тут неожиданное потребление огромного количества памяти.
...
Рейтинг: 0 / 0
07.12.2016, 18:02
    #39362052
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
BlazkowiczТут не совсем обычная утечка. Тут неожиданное потребление огромного количества памяти.
ну, он же про БЛ ничего не говорит. Он копает только то что знает.
Если неожиданность связана с БЛ, то вполне может быть копирование обектов через цикл в миллион без закрытия.
Так было у меня.
Пусть копает дальше...со всех сторон).
...
Рейтинг: 0 / 0
09.12.2016, 09:37
    #39363148
publexus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
Всем спасибо, проблема решена.

В один прекрасный момент удалось поймать момент роста памяти и снять дапм памяти (картинка в приложении). По картинке видно, что создано много LinkedCaseInsensitiveMap, которые возвращает JdbcTemplate при запросе. Начал копать и оказалось, что один из аналитических запросов на аномальном распределении данных возвращает очень много данных (сам запрос сложный с иерархией). После его модификации полет нормальный.
...
Рейтинг: 0 / 0
09.12.2016, 09:45
    #39363155
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Java heap overhead, memory leaks
publexusПри этом в данное время отсутствуют какие либо отклонения в пользовательской активности, либо аномальные вычислительные процессы
publexusодин из аналитических запросов на аномальном распределении данных возвращает очень много данных
Ну, вот как так, взять и отбросить один из самых вероятных сценариев, не имея на то весомых причин?
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Java heap overhead, memory leaks / 25 сообщений из 26, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]