|
|
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
Работает приложение на 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 принудительно выполнять полную очистку с определенным периодом (если это поможет)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 16:04 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
Какой тип сборщика? Какие размеры поколений? Про VisualVM пишут что он с большими кучами никак не справляется. Для анализа больших куч желательно иметь платный профайлер под рукой. Другое дело что ещё нужно и дамп как-то снять. Настройте и читайте GC Log в продакшне. Напишите триггер, который бы пробовал сделать дамп не на 16Gb, а на 4-8, при условии что 1,5Gb - нормальная загрузка. Сопаставьте время в GC Log-е с логом приложения и посмотрите что же реально происходит в момент стремительного роста. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 16:12 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
Еще картинка из VisualVM в добавление к предыдущей: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 16:40 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
Параметры ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 16:41 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
Eden я бы сделал побольше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 16:47 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
publexusПараметры MaxPermSize у вас не работает, так как у вас Metaspace вместо него. Отключать GCOverheadLimit это всё равно что бороться с пожаром путём отключения пожарной сигнализации. Тут немного про young. Хотя дело не в нём. https://blogs.oracle.com/jonthecollector/entry/the_second_most_important_gc Есть какие-то асинхронные процессы в приложении? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 16:54 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
publexusЧто происходит? И как заставить GC принудительно выполнять полную очистку с определенным периодом (если это поможет)? попробуй анализ кода на закрытие ресурсов в коде. У меня помогло. Правда смотрел сам глазами)). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 16:58 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, Да, асинхронные процессы есть: по запросу пользователя может запускаться несколько потоков, каждый из которых может оперировать своим (неразделяемым) набором hashmaps. Но в момент роста памяти кардинальных отклонений от стандартного режима нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 17:01 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
publexusПараметрыЗадлянафига гигантская разбежка между минимальным и максимальным размером кучи? Сделайте одинаково и, как уже советовали ~3-4Гб. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 17:03 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
publexusИ как заставить GC принудительно выполнять полную очистку с определенным периодом (если это поможет)? Это вообще никак не поможет. Есть молодое поколение - там сборка происходит часто в фоновом режиме и без каких либо телодвижений. Есть старое поколение - там сборка происходит редко, потому что сборка в старом поколении включает Stop-the-world фазы, который для многопользовательского сервера очень вредны. У вас старое поколение забивается под завязку и многократный вызов GC ничего не освобождает. Так что насильный вызов вряд ли приведёт к другому результату. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 17:03 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
publexusДа, асинхронные процессы есть: по запросу пользователя может запускаться несколько потоков, каждый из которых может оперировать своим (неразделяемым) набором hashmaps. Но в момент роста памяти кардинальных отклонений от стандартного режима нет. Ну, я имел ввиду что-то типа RxJava. С такими решениями есть классический косяк, когда событие уходит в цикл между разными потоками, а каждый вызов создаёт кучу объектов. Единственное что странно, что у вас эти данные где-то в глобальном хранилище оседают. Судя по графику они почти сразу в tenured улетают и в Eden особо не задерживаются. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 17:06 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
publexusТакое ощущение, что GC просто перестает собирать мусор. Что происходит? И как заставить GC принудительно выполнять полную очистку с определенным периодом (если это поможет)? Еслиб он перестал - то оранжевенького над сининьким не было бы. А так - есть. Делать dump. Находить машину с бOльшим количеством памяти (чем ваши 16). Загружать в профайлер (в VisualVM не соглашаться на полный анализ - надоест ждать). И смотреть что стало отъедать память. Еще не плохо бы настроить какие-нибудь триггера, хоть в кроне, хоть в заббиксе, и как только jmx сообщает, что съело больше 3 гигов начать делать последовательные дампы. Можно будет сравнить чем стало прирастать. Например в Котяре как-то стали сессии на websocket запросах виснуть. Новые переоткрывались. А старые за собой тянули все и не отпускали. Смотреть надо, чем прирастает и какой gc_root держит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 18:45 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
Вы обычные мапы используете или какую-то разновидность по типу Weak\Soft? Есть ли места, где создаются большие массивы, которые могут не влезть в Eden? Размер стэка у потоков дефолтный? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.12.2016, 20:18 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
забыл никВы обычные мапы используете или какую-то разновидность по типу Weak\Soft? Есть ли места, где создаются большие массивы, которые могут не влезть в Eden? Размер стэка у потоков дефолтный? Настройки стека не трогал. В вычислениях используются обычные HashMap, которых по моим подсчетам должно создаваться максимум несколько тысяч одновременно. Также довольно интенсивно используются списки мапы возвращаемые spring JdbcTemplate, которые без изменений далее передаются на отображение в primefaces datable. Таких, по моим подсчетам, одновременно может создаваться несколько десятков тысяч. Но их намного больше, как показывает картинка, которая снята в момент обычной активности, при использовании памяти в районе 2ГБ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.12.2016, 11:37 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
publexusВ вычислениях используются обычные HashMap, которых по моим подсчетам должно создаваться максимум несколько тысяч одновременно. Заведите глобальный счетчик, и логируйте его. Тогда будет понятно косяк в этом коде или где-то ещё. Не удивлюсь если ваша ситуация вообще сюрприз от GlassFish. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.12.2016, 11:41 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
publexusВ вычислениях используются обычные HashMap, которых по моим подсчетам должно создаваться максимум несколько тысяч одновременно. А как часто они по Вашему должны исчезать? Тем юолее, что их у Вас не так уж и много -74 тысячи. В принципе, можно и сейчас посмотреть на корни, которые их держат. Но интереснее IMHO - там на картинке буковки Сompare. И именно тогда, когда начинается рост. Ловля блох в момент нормальной работы может быть никак не связана с причиной лавионообразного роста. Может Вас вообще кто хакает и начинает утягивать базу в виде одного большого XML. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.12.2016, 14:20 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
publexusТакже довольно интенсивно используются списки мапы возвращаемые spring JdbcTemplate вы работает с БД? Тогда почему нет ни слова про БД? Про закрытие соединения или возврат в пул? Про нагрузку и статистику со стороны БД? У вас просто драйвер JDBC может съесть всю память при некорректном коде. IMHO ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.12.2016, 14:43 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
Petro123publexusТакже довольно интенсивно используются списки мапы возвращаемые spring JdbcTemplate вы работает с БД? Тогда почему нет ни слова про БД? Про закрытие соединения или возврат в пул? Про нагрузку и статистику со стороны БД? У вас просто драйвер JDBC может съесть всю память при некорректном коде. IMHO Для соединения к БД использую Hicari, настроенный как бин, который передаю JdbcTemplate и использую исключительно его для доступа к БД. Там, как мне кажется придраться не к чему. Соединения к базе и активность в ней я анализировал, там ничего особенного не было. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.12.2016, 16:26 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
Сергей АрсеньевpublexusВ вычислениях используются обычные HashMap, которых по моим подсчетам должно создаваться максимум несколько тысяч одновременно. А как часто они по Вашему должны исчезать? Тем юолее, что их у Вас не так уж и много -74 тысячи. В принципе, можно и сейчас посмотреть на корни, которые их держат. Но интереснее IMHO - там на картинке буковки Сompare. И именно тогда, когда начинается рост. Ловля блох в момент нормальной работы может быть никак не связана с причиной лавионообразного роста. Может Вас вообще кто хакает и начинает утягивать базу в виде одного большого XML. :) В том то и дело, что я не могу сравнить или посмотреть что там в памяти аномального сидит. Как я писал выше, если в момент роста памяти в VisualVM включить мусорщик принудительно, то память очищается практически полностью (мегабайт до 200-300), аномальный рост памяти обрывается и приложение функционирует нормально. Если я выполняю Heap dump, то перед снятием снимка памяти также почему-то происходит запуск мусорщика и память тоже очищается. Если же память переполнилась, то процесс jvm просто подвисает - не реагирует ни на какие запросы, asadmin не отвечает, помогает только kill -9. Если VisualVM была подключена к jvm, то спустя некоторое время после переполнения тоже отключается от нее. Естественно, снять дапм в этом случае тоже не получается. Т.е. я никак не могу получить информацию о том, что же там растет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.12.2016, 16:39 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
publexusТам, как мне кажется придраться не к чему. Соединения к базе и активность в ней я анализировал, там ничего особенного не было. ну если вы так уверены). То и разговора нет. Т.к. банальное отсутствие (recordSet\Statement\...).Close даст утечку памяти. Удачи! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.12.2016, 17:09 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
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 осилить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.12.2016, 17:31 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
Petro123ну если вы так уверены). То и разговора нет. Т.к. банальное отсутствие (recordSet\Statement\...).Close даст утечку памяти. Удачи! Тут не совсем обычная утечка. Тут неожиданное потребление огромного количества памяти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.12.2016, 17:32 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
BlazkowiczТут не совсем обычная утечка. Тут неожиданное потребление огромного количества памяти. ну, он же про БЛ ничего не говорит. Он копает только то что знает. Если неожиданность связана с БЛ, то вполне может быть копирование обектов через цикл в миллион без закрытия. Так было у меня. Пусть копает дальше...со всех сторон). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.12.2016, 18:02 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
Всем спасибо, проблема решена. В один прекрасный момент удалось поймать момент роста памяти и снять дапм памяти (картинка в приложении). По картинке видно, что создано много LinkedCaseInsensitiveMap, которые возвращает JdbcTemplate при запросе. Начал копать и оказалось, что один из аналитических запросов на аномальном распределении данных возвращает очень много данных (сам запрос сложный с иерархией). После его модификации полет нормальный. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2016, 09:37 |
|
||
|
Java heap overhead, memory leaks
|
|||
|---|---|---|---|
|
#18+
publexusПри этом в данное время отсутствуют какие либо отклонения в пользовательской активности, либо аномальные вычислительные процессы publexusодин из аналитических запросов на аномальном распределении данных возвращает очень много данных Ну, вот как так, взять и отбросить один из самых вероятных сценариев, не имея на то весомых причин? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2016, 09:45 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=39361390&tid=2123410]: |
0ms |
get settings: |
7ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
53ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
52ms |
get tp. blocked users: |
1ms |
| others: | 205ms |
| total: | 351ms |

| 0 / 0 |
