Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Java |
![]() ![]() |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
WGA Member Откуда: Сообщений: 408 |
Всем доброго дня! Прошу помощи в идентификации проблемы. Dev-сервер Wildfly 11, деплоятся несколько инстансов одного EAR-приложения. Редеплои случаются часто только для сборки из ветки master, сновной ветки разработки. Параметры памяти: JAVA_OPTS="-Xms1536m -Xmx4096m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=1512m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapoom.hprof"Хипдамп имеется, загрузил в MAT и ничего не понимаю... ![]() В отчете Dominator tree 3 основных строчки: Class Name | Shallow Heap | Retained Heap | PercentageВ Top consumers та же самая картина. Если посмотреть List objects -> with outgoing references для самого большого объекта, то видим такие результаты: Class Name | Shallow Heap | Retained HeapВидно, что java.lang.Thread @ 0x6d9632fd8 замыкается на себя. Ничего не понятно... Если бы память "текла" через класслоадеры, то вроде как Metaspace должно бы исчерпаться, а не Heap. Или я чего-то не догоняю? |
26 сен 19, 13:06 [21979717] Ответить | Цитировать Сообщить модератору |
WGA Member Откуда: Сообщений: 408 |
С группировкой по классам К сообщению приложен файл. Размер - 20Kb |
26 сен 19, 13:20 [21979731] Ответить | Цитировать Сообщить модератору |
Leonid Kudryavtsev Member Откуда: Сообщений: 9316 |
AFAIK N1 полно багов с редеплоем, из-за которых память не чистится. Но AFAIK тогда обычно утекает Perm Gen, а не Heap AFAIK N2 Ты смотрешь root объект который имеет ссылку верхнего уровня на не освобожденные объекты. Возможно из-за редиплоя потоки корректно не останавливаются, т.е. см. п. 1. Ну и смотреть, где и как порождаются потоки и как останавливаются |
||
26 сен 19, 13:26 [21979739] Ответить | Цитировать Сообщить модератору |
WGA Member Откуда: Сообщений: 408 |
Интересное наблюдение. Просматривая отчет Leak Suspects, обнаружил такую проблему. The thread java.lang.Thread @ 0x6d9632fd8 default task-4 keeps local variables with total size 1,170,908,752 (33.08%) bytes.Посмотрел детали. Accumulated Objects in Dominator TreeЦелая туча абсолютно однотипных объектов, более 200000, все по 5800 байт retained size. Просмотрел содержимое, а там проскакивают enum'ы, которые в используются в сущностях хибернейтовских. Похоже это данные в ThreadLocal текут. Проблема в том, что нигде явно ThreadLocal не используется... Какая-то хрень в Хибернейте, но не исключено, что и аппликейшн код не без косяков. |
||||
26 сен 19, 14:06 [21979832] Ответить | Цитировать Сообщить модератору |
ivanra Member Откуда: Сообщений: 889 |
Осталось посмотреть кто держит этот массивjava.lang.Object[240097] @ 0x76607fd50Скорее всего какой-нибудь ArrayList. Ну и дальше вверх надо смотреть кто хозяин |
26 сен 19, 14:11 [21979851] Ответить | Цитировать Сообщить модератору |
WGA Member Откуда: Сообщений: 408 |
Class Name | Shallow Heap | Retained HeapТак понимаю, <Java Local> - это thread local треда "default task-4 Thread". Почему-то окольными путями добрался к этому массиву, видимо, чего-то в MAT я не догоняю. Или thread local - штука особенная. Понять бы, что это за объекты. Вот что выводит outgoing references для ArrayList Class Name | Shallow Heap | Retained HeapДвумерный массив, вроде бы как. |
||
26 сен 19, 14:22 [21979867] Ответить | Цитировать Сообщить модератору |
WGA Member Откуда: Сообщений: 408 |
Очень похоже на сериализованные объекты доменных классов. И похоже, что они остаются в памяти только при редеплое, иначе бы прод бы падал с завидной регулярностью, чего нет в действительности. И у нас не используется кэш 2-го уровня. Откуда же эта зараза берется?.. |
26 сен 19, 14:37 [21979896] Ответить | Цитировать Сообщить модератору |
mayton Member Откуда: loopback Сообщений: 50489 |
WGA, вы можете по отчоту где лежат 1,170,884,208 объектов кликнуть мышкой и посмотреть какой бизнесовый экзепляр там лежит? |
26 сен 19, 14:41 [21979904] Ответить | Цитировать Сообщить модератору |
WGA Member Откуда: Сообщений: 408 |
Class Name | Shallow Heap | Retained HeapСамих объектов нет, похоже это сериализованное представление какой-то entity. Выборочно нашел, к чему относится UUID=1ffb6a1f-d7b4-4014-99c3-9023029c3aec, это экземпляр сущности Currency (RUB). Т.е. в threadlocal рабочего пула потоков Wildfly зависают данные. При редеплое ссылки остаются и держат как heap, так и metaspace, просто под metaspace выделно много памяти, heap кончается быстрее, похоже. |
||
26 сен 19, 14:49 [21979913] Ответить | Цитировать Сообщить модератору |
ivanra Member Откуда: Сообщений: 889 |
WGA,
Нет, эта таблица хранится в переменной threadLocals, можно посмотреть в jdk. Советую для начала понять, что это за поток. Вызвать для него контекстное меню Java Basics - Thread Details, там будет стек, по которому уже можно догадаться, чем поток занимается |
||
26 сен 19, 14:49 [21979914] Ответить | Цитировать Сообщить модератору |
ivanra Member Откуда: Сообщений: 889 |
Если недостаточно понятно - наименования полей всегда видно, именно такие же, как в исходном коде jdk. Если же мы видим <Java Local> - то это переменная, объявленная в методе, а не поле. Этот метод почему-то никак не может закончиться и освободить переменную. Поэтому смотрим в стек и догадываемся, что метод делает |
||||
26 сен 19, 14:58 [21979934] Ответить | Цитировать Сообщить модератору |
mayton Member Откуда: loopback Сообщений: 50489 |
Мне кажется этот зубчатый (jagged) массив порождает не код программиста а какой-то фреймворк. Что за фреймворки у вас используются? |
26 сен 19, 15:00 [21979936] Ответить | Цитировать Сообщить модератору |
WGA Member Откуда: Сообщений: 408 |
Вот стектрейс треда:
Class Name | Shallow Heap | Retained HeapОтсюда
|
|||||||
26 сен 19, 15:02 [21979941] Ответить | Цитировать Сообщить модератору |
WGA Member Откуда: Сообщений: 408 |
Используемые технологии из спецификации: 1. JPA - под капотом Hibernate 5.1.10.Final. 2. JMS - ActiveMQ. 3. JAX RS - ReastEasy Но по всем видать, дело в JPA. |
||
26 сен 19, 15:06 [21979948] Ответить | Цитировать Сообщить модератору |
mayton Member Откуда: loopback Сообщений: 50489 |
|- [436] byte[26] @ 0x6f45318b0 2018-05-28 11:07:02.658117 Интересно. Строки сериализованы в байты для экономии. В ASCIIZ. |
26 сен 19, 15:12 [21979954] Ответить | Цитировать Сообщить модератору |
ivanra Member Откуда: Сообщений: 889 |
WGA, Вот, а теперь смотрим исходники своих методов, которые попали в этот стек, начиная с
Судя по всему, там мега запросы к базе. Возможно, во время выполнения произошел редеплой. Как там работает в таких случаях хибернейт не знаю, но к запросам лучше приглядеться |
||
26 сен 19, 15:12 [21979958] Ответить | Цитировать Сообщить модератору |
mayton Member Откуда: loopback Сообщений: 50489 |
EhCache сбоку где-то прикручен? По eviction-policy еще не успел кеши зачистить и засрал весь хип. |
26 сен 19, 15:17 [21979963] Ответить | Цитировать Сообщить модератору |
Leonid Kudryavtsev Member Откуда: Сообщений: 9316 |
у нас дамп памяти вообще был замусорен byte[] массивами от Java JDBC был. Долго и нудно техподдерка Oracle предлагала JDBC проапгрейдить, потом выяснилось, что косяк в нашем коде. Не всегда statement.close вызывали, вот JDBC буфера в памяти и оставались. Самое веселое, что просмоторшики дампов данную память относили к категории "может быть очищена", в результате по версии просмоторшиков дампов вообще был бред 2 Gb heap, из них 1.8 Gb "может быть очищена", но упали с out of memory. |
26 сен 19, 15:20 [21979967] Ответить | Цитировать Сообщить модератору |
ivanra Member Откуда: Сообщений: 889 |
Leonid Kudryavtsev, да, тут скорее всего ошибка в бизнес коде. Судя по названию метода CompanyFullView можно предположить, что происходил обход дерева подразделений, и что-то пошло не так. Например, цикл. Или проблема n+1 |
26 сен 19, 15:26 [21979976] Ответить | Цитировать Сообщить модератору |
Leonid Kudryavtsev Member Откуда: Сообщений: 9316 |
Из-за редеплоя "просрали" classloader, из-за просранного класслоадера не смогли почистить не закрытые сессии/статменты? как предположение |
||
26 сен 19, 15:27 [21979978] Ответить | Цитировать Сообщить модератору |
Leonid Kudryavtsev Member Откуда: Сообщений: 9316 |
Если 88 это кол-во копий classLoader'а, то IMHO налицо классический bug с редиплоем Как-то класлоадеров многовато, на мой взгляд. |
||||
26 сен 19, 15:29 [21979982] Ответить | Цитировать Сообщить модератору |
Leonid Kudryavtsev Member Откуда: Сообщений: 9316 |
+ где-то в коде не закрываются сессии/стайтменты одно наслоилось на другое, получилось 2 Gb мусора. Если бы открытых "жрущих" сессии/стайтментов не было бы, то рано или поздно уплали бы по классической out of perm gen (или метаспейс). А так, JDBC heap засисрает быстрее, чем классы perm gen IMHO |
26 сен 19, 15:33 [21979989] Ответить | Цитировать Сообщить модератору |
ivanra Member Откуда: Сообщений: 889 |
Leonid Kudryavtsev, кеш это обычно различные варианты HashMap-а, а тут ArrayList. Целый гиг данных, прочитанный из базы каким-то одним методом. Не так давно мы фильмы такого объема смотрели, для БД это многовато |
26 сен 19, 15:42 [21980007] Ответить | Цитировать Сообщить модератору |
Leonid Kudryavtsev Member Откуда: Сообщений: 9316 |
Не правда ваша. В наше время программистам 2 Гига засрать - как 2 пальца обосновать ))) Банальные буффера для обмена по сети, для Oracle JDBC thin драйвера по 32-64 MB - запросто! Даже для простейшего "select dummy from dual" - дабы не жалко (при нормальной работе они реиспользуются и очищаются). Здесь же видим 200 НЕ закрытых Statement'ов в 88 не до убитых копиях приложений (88 штук класслоадеров). |
||
26 сен 19, 15:50 [21980018] Ответить | Цитировать Сообщить модератору |
WGA Member Откуда: Сообщений: 408 |
Судя по куче разных объектов типа Currency с одним IDшником (тот самый RUB), возможно equals/hashCode работают некорректно и Hibernate не может понять, что это один и тот же объект и плодит их со страшной силой. Надо порядок в сущностях навести. В общем ушел пытаться воспроизвести проблему в своей песочнице. |
||||||||||
26 сен 19, 15:56 [21980025] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
Все форумы / Java | ![]() |