Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Memory Leak?  [new]
WGA
Member

Откуда:
Сообщений: 392
Всем доброго дня!

Прошу помощи в идентификации проблемы.

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
--------------------------------------------------------------------------------------------------
java.lang.Thread @ 0x6d9632fd8 default task-4 Thread | 120 | 1,170,908,752 | 33.08%
java.lang.Thread @ 0x6d8604ce0 default task-2 Thread | 120 | 788,671,152 | 22.28%
java.lang.Thread @ 0x6e0ae8390 default task-10 Thread| 120 | 620,186,896 | 17.52%
--------------------------------------------------------------------------------------------------
В Top consumers та же самая картина. Если посмотреть List objects -> with outgoing references для самого большого объекта, то видим такие результаты:
Class Name                                                           | Shallow Heap | Retained Heap
----------------------------------------------------------------------------------------------------
java.lang.Thread @ 0x6d9632fd8 default task-4 Thread | 120 | 1,170,908,752
............................
| | | | | | | | | | | | | | |- <Java Local> java.lang.Thread @ 0x6d9632fd8 default task-4 Thread| 120 | 1,170,908,752
----------------------------------------------------------------------------------------------------
Видно, что java.lang.Thread @ 0x6d9632fd8 замыкается на себя. Ничего не понятно... Если бы память "текла" через класслоадеры, то вроде как Metaspace должно бы исчерпаться, а не Heap. Или я чего-то не догоняю?
26 сен 19, 13:06    [21979717]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
WGA
Member

Откуда:
Сообщений: 392
С группировкой по классам

К сообщению приложен файл. Размер - 20Kb
26 сен 19, 13:20    [21979731]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7927
WGA
...Редеплои случаются часто...

AFAIK N1
полно багов с редеплоем, из-за которых память не чистится. Но AFAIK тогда обычно утекает Perm Gen, а не Heap

AFAIK N2
Ты смотрешь root объект который имеет ссылку верхнего уровня на не освобожденные объекты. Возможно из-за редиплоя потоки корректно не останавливаются, т.е. см. п. 1. Ну и смотреть, где и как порождаются потоки и как останавливаются
26 сен 19, 13:26    [21979739]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
WGA
Member

Откуда:
Сообщений: 392
Leonid Kudryavtsev
WGA
...Редеплои случаются часто...

AFAIK N1
полно багов с редеплоем, из-за которых память не чистится. Но AFAIK тогда обычно утекает Perm Gen, а не Heap
Да, утечки PermGen - штука известная. Сам удивлен. В Java 8 не PermGen, а MetaSpace, но вряд ли это имеет отношение к сути проблемы.

Интересное наблюдение. Просматривая отчет Leak Suspects, обнаружил такую проблему.
The thread java.lang.Thread @ 0x6d9632fd8 default task-4 keeps local variables with total size 1,170,908,752 (33.08%) bytes.

The memory is accumulated in one instance of "java.lang.Object[]" loaded by "<system class loader>".
The stacktrace of this Thread is available. See stacktrace.



Keywords
java.lang.Object[]
Details »
Посмотрел детали.
Accumulated Objects in Dominator Tree

Class Name | Shallow Heap | Retained Heap | Percentage
----------------------------------------------------------------------------------
java.lang.Object[240097] @ 0x76607fd50| 960,408 | 1,170,884,208 | 33.08%
|- byte[461][] @ 0x71321bd60 | 1,864 | 5,800 | 0.00%
|- byte[461][] @ 0x6fe760148 | 1,864 | 5,800 | 0.00%
|- byte[461][] @ 0x70c33b5b0 | 1,864 | 5,800 | 0.00%
----------------------------------------------------------------------------------
Целая туча абсолютно однотипных объектов, более 200000, все по 5800 байт retained size. Просмотрел содержимое, а там проскакивают enum'ы, которые в используются в сущностях хибернейтовских. Похоже это данные в ThreadLocal текут. Проблема в том, что нигде явно ThreadLocal не используется... Какая-то хрень в Хибернейте, но не исключено, что и аппликейшн код не без косяков.
26 сен 19, 14:06    [21979832]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
ivanra
Member

Откуда:
Сообщений: 860
Осталось посмотреть кто держит этот массив
java.lang.Object[240097] @ 0x76607fd50
Скорее всего какой-нибудь ArrayList. Ну и дальше вверх надо смотреть кто хозяин
26 сен 19, 14:11    [21979851]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
WGA
Member

Откуда:
Сообщений: 392
ivanra
Осталось посмотреть кто держит этот массив
java.lang.Object[240097] @ 0x76607fd50
Скорее всего какой-нибудь ArrayList. Ну и дальше вверх надо смотреть кто хозяин

Class Name                                                           | Shallow Heap | Retained Heap
----------------------------------------------------------------------------------------------------
java.util.ArrayList @ 0x6f40dd208 | 24 | 1,170,884,232
'- <Java Local> java.lang.Thread @ 0x6d9632fd8 default task-4 Thread| 120 | 1,170,908,752
----------------------------------------------------------------------------------------------------
Так понимаю, <Java Local> - это thread local треда "default task-4 Thread". Почему-то окольными путями добрался к этому массиву, видимо, чего-то в MAT я не догоняю. Или thread local - штука особенная.

Понять бы, что это за объекты. Вот что выводит outgoing references для ArrayList
Class Name                                                     | Shallow Heap | Retained Heap
----------------------------------------------------------------------------------------------
java.util.ArrayList @ 0x6f40dd208 | 24 | 1,170,884,232
|- <class> class java.util.ArrayList @ 0x6c2c06b90 System Class| 24 | 24
|- elementData java.lang.Object[240097] @ 0x76607fd50 | 960,408 | 1,170,884,208
| |- <class> class java.lang.Object[] @ 0x6c2b11e18 | 0 | 0
| |- [4467] byte[461][] @ 0x6f3690178 | 1,864 | 5,800
| |- [4466] byte[461][] @ 0x6f44dd248 | 1,864 | 5,800
| |- [4417] byte[461][] @ 0x6f44e5e10 | 1,864 | 5,800
| |- [4418] byte[461][] @ 0x6f44fb1d0 | 1,864 | 5,800
| |- [3768] byte[461][] @ 0x6f45212f0 | 1,864 | 5,800
----------------------------------------------------------------------------------------------
Двумерный массив, вроде бы как.
26 сен 19, 14:22    [21979867]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
WGA
Member

Откуда:
Сообщений: 392
Очень похоже на сериализованные объекты доменных классов. И похоже, что они остаются в памяти только при редеплое, иначе бы прод бы падал с завидной регулярностью, чего нет в действительности. И у нас не используется кэш 2-го уровня. Откуда же эта зараза берется?..
26 сен 19, 14:37    [21979896]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
mayton
Member

Откуда: loopback
Сообщений: 42385
WGA,

вы можете по отчоту где лежат 1,170,884,208 объектов кликнуть мышкой и посмотреть какой бизнесовый экзепляр
там лежит?
26 сен 19, 14:41    [21979904]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
WGA
Member

Откуда:
Сообщений: 392
mayton
WGA,

вы можете по отчоту где лежат 1,170,884,208 объектов кликнуть мышкой и посмотреть какой бизнесовый экзепляр
там лежит?
Могу и уже сделал. Только не все древо развернул.
Class Name                                                                 | Shallow Heap | Retained Heap
----------------------------------------------------------------------------------------------------------
java.util.ArrayList @ 0x6f40dd208 | 24 | 1,170,884,232
|- <class> class java.util.ArrayList @ 0x6c2c06b90 System Class | 24 | 24
|- elementData java.lang.Object[240097] @ 0x76607fd50 | 960,408 | 1,170,884,208
| |- <class> class java.lang.Object[] @ 0x6c2b11e18 | 0 | 0
....................................................................................................................... (пропущены строки)
| |- [4460] byte[461][] @ 0x6f4530fd8 | 1,864 | 5,800
| | |- <class> class byte[][] @ 0x6c05e7188 | 0 | 0
| | |- [450] byte[3] @ 0x6f4531720 ... | 24 | 24
| | |- [449] byte[3] @ 0x6f4531738 643 | 24 | 24
| | |- [448] byte[10] @ 0x6f4531750 .......... | 32 | 32
| | |- [447] byte[9] @ 0x6f4531770 MASCULINE | 32 | 32
| | |- [446] byte[10] @ 0x6f4531790 .......... | 32 | 32
| | |- [445] byte[10] @ 0x6f45317b0 .......... | 32 | 32
| | |- [444] byte[12] @ 0x6f45317d0 ............ | 32 | 32
| | |- [443] byte[6] @ 0x6f45317f0 ...... | 24 | 24
| | |- [442] byte[8] @ 0x6f4531808 FEMININE | 24 | 24
| | |- [441] byte[14] @ 0x6f4531820 .............. | 32 | 32
| | |- [440] byte[14] @ 0x6f4531840 .............. | 32 | 32
| | |- [439] byte[12] @ 0x6f4531860 ............ | 32 | 32
| | |- [438] byte[6] @ 0x6f4531880 ...... | 24 | 24
| | |- [437] byte[3] @ 0x6f4531898 RUB | 24 | 24
| | |- [436] byte[26] @ 0x6f45318b0 2018-05-28 11:07:02.658117 | 48 | 48
| | |- [435] byte[26] @ 0x6f45318e0 2018-05-28 11:07:02.658117 | 48 | 48
| | |- [434] byte[1] @ 0x6f4531910 0 | 24 | 24
| | |- [433] byte[36] @ 0x6f4531928 1ffb6a1f-d7b4-4014-99c3-9023029c3aec| 56 | 56
| | |- [365] byte[12] @ 0x6f4531960 LEGAL_ENTITY | 32 | 32
| | |- [360] byte[1] @ 0x6f4531980 f | 24 | 24
| | |- [354] byte[36] @ 0x6f4531998 dfe8f44a-3bb9-451e-80d9-8be2cce0d2ee| 56 | 56
| | |- [352] byte[36] @ 0x6f45319d0 53bafd08-959e-42f5-b67e-b1125df665e7| 56 | 56
| | |- [351] byte[23] @ 0x6f4531a08 2019-02-07 21:36:54.122 | 40 | 40
----------------------------------------------------------------------------------------------------------
Самих объектов нет, похоже это сериализованное представление какой-то entity. Выборочно нашел, к чему относится UUID=1ffb6a1f-d7b4-4014-99c3-9023029c3aec, это экземпляр сущности Currency (RUB). Т.е. в threadlocal рабочего пула потоков Wildfly зависают данные. При редеплое ссылки остаются и держат как heap, так и metaspace, просто под metaspace выделно много памяти, heap кончается быстрее, похоже.
26 сен 19, 14:49    [21979913]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
ivanra
Member

Откуда:
Сообщений: 860
WGA,

автор
Так понимаю, <Java Local> - это thread local треда "default task-4 Thread".

Нет, эта таблица хранится в переменной threadLocals, можно посмотреть в jdk.
Советую для начала понять, что это за поток. Вызвать для него контекстное меню Java Basics - Thread Details, там будет стек, по которому уже можно догадаться, чем поток занимается
26 сен 19, 14:49    [21979914]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
ivanra
Member

Откуда:
Сообщений: 860
ivanra
WGA,

автор
Так понимаю, <Java Local> - это thread local треда "default task-4 Thread".

Нет, эта таблица хранится в переменной threadLocals, можно посмотреть в jdk.

Если недостаточно понятно - наименования полей всегда видно, именно такие же, как в исходном коде jdk. Если же мы видим <Java Local> - то это переменная, объявленная в методе, а не поле. Этот метод почему-то никак не может закончиться и освободить переменную. Поэтому смотрим в стек и догадываемся, что метод делает
26 сен 19, 14:58    [21979934]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
mayton
Member

Откуда: loopback
Сообщений: 42385
Мне кажется этот зубчатый (jagged) массив порождает не код программиста а какой-то фреймворк.
Что за фреймворки у вас используются?
26 сен 19, 15:00    [21979936]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
WGA
Member

Откуда:
Сообщений: 392
ivanra
WGA,

автор
Так понимаю, <Java Local> - это thread local треда "default task-4 Thread".

Нет, эта таблица хранится в переменной threadLocals, можно посмотреть в jdk.
Советую для начала понять, что это за поток. Вызвать для него контекстное меню Java Basics - Thread Details, там будет стек, по которому уже можно догадаться, чем поток занимается
Да, действительно, threadLocals - это отдельное поле.
Вот стектрейс треда:
+
default task-4
at org.postgresql.core.PGStream.receiveTupleV3()[[B (PGStream.java:435)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(Lorg/postgresql/core/ResultHandler;I)V (QueryExecutorImpl.java:2174)
at org.postgresql.core.v3.QueryExecutorImpl.execute(Lorg/postgresql/core/Query;Lorg/postgresql/core/ParameterList;Lorg/postgresql/core/ResultHandler;III)V (QueryExecutorImpl.java:309)
at org.postgresql.jdbc.PgStatement.executeInternal(Lorg/postgresql/core/CachedQuery;Lorg/postgresql/core/ParameterList;I)V (PgStatement.java:446)
at org.postgresql.jdbc.PgStatement.execute(Lorg/postgresql/core/CachedQuery;Lorg/postgresql/core/ParameterList;I)V (PgStatement.java:370)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(I)Z (PgPreparedStatement.java:149)
at org.postgresql.jdbc.PgPreparedStatement.executeQuery()Ljava/sql/ResultSet; (PgPreparedStatement.java:108)
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery()Ljava/sql/ResultSet; (WrappedPreparedStatement.java:504)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(Ljava/sql/PreparedStatement;)Ljava/sql/ResultSet; (ResultSetReturnImpl.java:70)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.getResultSet(Ljava/sql/PreparedStatement;Lorg/hibernate/engine/spi/RowSelection;Lorg/hibernate/dialect/pagination/LimitHandler;ZLorg/hibernate/engine/spi/SessionImplementor;)Ljava/sql/ResultSet; (AbstractLoadPlanBasedLoader.java:434)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeQueryStatement(Ljava/lang/String;Lorg/hibernate/engine/spi/QueryParameters;ZLjava/util/List;Lorg/hibernate/engine/spi/SessionImplementor;)Lorg/hibernate/loader/plan/exec/internal/AbstractLoadPlanBasedLoader$SqlStatementWrapper; (AbstractLoadPlanBasedLoader.java:186)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(Lorg/hibernate/engine/spi/SessionImplementor;Lorg/hibernate/engine/spi/QueryParameters;Lorg/hibernate/loader/plan/exec/spi/LoadQueryDetails;ZLorg/hibernate/transform/ResultTransformer;Ljava/util/List;)Ljava/util/List; (AbstractLoadPlanBasedLoader.java:121)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(Lorg/hibernate/engine/spi/SessionImplementor;Lorg/hibernate/engine/spi/QueryParameters;Lorg/hibernate/loader/plan/exec/spi/LoadQueryDetails;ZLorg/hibernate/transform/ResultTransformer;)Ljava/util/List; (AbstractLoadPlanBasedLoader.java:86)
at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(Ljava/io/Serializable;Lorg/hibernate/engine/spi/SessionImplementor;)V (AbstractLoadPlanBasedCollectionInitializer.java:88)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(Ljava/io/Serializable;Lorg/hibernate/engine/spi/SessionImplementor;)V (AbstractCollectionPersister.java:688)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(Lorg/hibernate/event/spi/InitializeCollectionEvent;)V (DefaultInitializeCollectionEventListener.java:75)
at org.hibernate.internal.SessionImpl.initializeCollection(Lorg/hibernate/collection/spi/PersistentCollection;Z)V (SessionImpl.java:2004)
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork()Ljava/lang/Object; (AbstractPersistentCollection.java:567)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(Lorg/hibernate/collection/internal/AbstractPersistentCollection$LazyInitializationWork;)Ljava/lang/Object; (AbstractPersistentCollection.java:249)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(Z)V (AbstractPersistentCollection.java:563)
at org.hibernate.collection.internal.AbstractPersistentCollection.read()V (AbstractPersistentCollection.java:132)
at org.hibernate.collection.internal.PersistentBag.iterator()Ljava/util/Iterator; (PersistentBag.java:277)
at java.util.Spliterators$IteratorSpliterator.estimateSize()J (Spliterators.java:1821)
at java.util.Spliterator.getExactSizeIfKnown()J (Spliterator.java:408)
at java.util.stream.AbstractPipeline.copyInto(Ljava/util/stream/Sink;Ljava/util/Spliterator;)V (AbstractPipeline.java:480)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Ljava/util/stream/Sink;Ljava/util/Spliterator;)Ljava/util/stream/Sink; (AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Ljava/util/stream/PipelineHelper;Ljava/util/Spliterator;)Ljava/lang/Object; (ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(Ljava/util/stream/TerminalOp;)Ljava/lang/Object; (AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(Ljava/util/stream/Collector;)Ljava/lang/Object; (ReferencePipeline.java:499)
at ru.septagon.recs.rs.view.CompanyFullView$InnerCashRegisterView.of(Lru/septagon/recs/domain/organization/CashRegister;)Lru/septagon/recs/rs/view/CompanyFullView$InnerCashRegisterView; (CompanyFullView.java:199)
at ru.septagon.recs.rs.view.DivisionDetail$$Lambda$1899.apply(Ljava/lang/Object;)Ljava/lang/Object; (Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(Ljava/lang/Object;)V (ReferencePipeline.java:193)
at java.util.Iterator.forEachRemaining(Ljava/util/function/Consumer;)V (Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Ljava/util/function/Consumer;)V (Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(Ljava/util/stream/Sink;Ljava/util/Spliterator;)V (AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Ljava/util/stream/Sink;Ljava/util/Spliterator;)Ljava/util/stream/Sink; (AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Ljava/util/stream/PipelineHelper;Ljava/util/Spliterator;)Ljava/lang/Object; (ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(Ljava/util/stream/TerminalOp;)Ljava/lang/Object; (AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(Ljava/util/stream/Collector;)Ljava/lang/Object; (ReferencePipeline.java:499)
at ru.septagon.recs.rs.view.DivisionDetail.fill(Lru/septagon/recs/domain/organization/Division;)V (DivisionDetail.java:92)
at ru.septagon.recs.rs.view.DivisionDetail.of(Lru/septagon/recs/domain/organization/Division;)Lru/septagon/recs/rs/view/DivisionDetail; (DivisionDetail.java:51)
at ru.septagon.recs.rs.view.CompanyFullView$$Lambda$1898.apply(Ljava/lang/Object;)Ljava/lang/Object; (Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(Ljava/lang/Object;)V (ReferencePipeline.java:193)
at java.util.Iterator.forEachRemaining(Ljava/util/function/Consumer;)V (Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Ljava/util/function/Consumer;)V (Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(Ljava/util/stream/Sink;Ljava/util/Spliterator;)V (AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Ljava/util/stream/Sink;Ljava/util/Spliterator;)Ljava/util/stream/Sink; (AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Ljava/util/stream/PipelineHelper;Ljava/util/Spliterator;)Ljava/lang/Object; (ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(Ljava/util/stream/TerminalOp;)Ljava/lang/Object; (AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(Ljava/util/stream/Collector;)Ljava/lang/Object; (ReferencePipeline.java:499)
at ru.septagon.recs.rs.view.CompanyFullView.fill(Lru/septagon/recs/domain/organization/Company;)V (CompanyFullView.java:58)
at ru.septagon.recs.rs.view.CompanyFullView.of(Lru/septagon/recs/domain/organization/Company;)Lru/septagon/recs/rs/view/CompanyFullView; (CompanyFullView.java:49)
at ru.septagon.recs.rs.CompaniesResource$$Lambda$1895.apply(Ljava/lang/Object;)Ljava/lang/Object; (Unknown Source)
at ru.septagon.recs.service.CompanyService.getCompany(Ljava/util/UUID;Ljava/util/function/Function;)Ljava/lang/Object; (CompanyService.java:188)
...............................................................
А вот outgoing reference у того же самого потока
Class Name                                                                                           | Shallow Heap | Retained Heap
------------------------------------------------------------------------------------------------------------------------------------
java.lang.Thread @ 0x6d9632fd8 default task-4 Thread | 120 | 1,170,908,752
|- <Java Local> java.lang.Thread @ 0x6d9632fd8 default task-4 Thread | 120 | 1,170,908,752
|- <Java Local> java.util.ArrayList @ 0x6f40dd208 | 24 | 1,170,884,232
|- <Java Local> org.postgresql.core.v3.QueryExecutorImpl @ 0x6e27c97b8 | 200 | 1,154,864
|- contextClassLoader org.jboss.modules.ModuleClassLoader @ 0x6e56718d8 | 88 | 141,432
|- <Java Local> org.hibernate.loader.plan.exec.internal.BasicCollectionLoadQueryDetails @ 0x6ef8b9180| 48 | 117,224
|- <Java Local> org.hibernate.engine.internal.StatefulPersistenceContext @ 0x6f38e2680 | 104 | 69,072
|- <Java Local> org.postgresql.core.PGStream @ 0x6e27c9880 | 64 | 35,360
|- <Java Local> org.jboss.modules.ModuleClassLoader @ 0x6c2c19dd0 | 88 | 33,368
|- threadLocals java.lang.ThreadLocal$ThreadLocalMap @ 0x6d96331d8 | 24 | 9,488
|- <Java Local> io.undertow.servlet.spec.HttpServletRequestImpl @ 0x6f391dd00 | 72 | 4,920
|- <Java Local> org.jboss.resteasy.spi.ResteasyUriInfo @ 0x6f40dd670 | 96 | 4,904
|- <Java Local> byte[461][] @ 0x76aaf9a98 | 1,864 | 4,000
------------------------------------------------------------------------------------------------------------------------------------
Отсюда
4. Java Local: All local variables (parameters, objects or methods in thread stacks)
Это просто локальные переменные. Все интереснее и интереснее...
26 сен 19, 15:02    [21979941]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
WGA
Member

Откуда:
Сообщений: 392
mayton
Мне кажется этот зубчатый (jagged) массив порождает не код программиста а какой-то фреймворк.
Что за фреймворки у вас используются?
JEE7, реализация - Wildfly 11.
Используемые технологии из спецификации:
1. JPA - под капотом Hibernate 5.1.10.Final.
2. JMS - ActiveMQ.
3. JAX RS - ReastEasy

Но по всем видать, дело в JPA.
26 сен 19, 15:06    [21979948]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
mayton
Member

Откуда: loopback
Сообщений: 42385
|- [436] byte[26] @ 0x6f45318b0  2018-05-28 11:07:02.658117

Интересно. Строки сериализованы в байты для экономии. В ASCIIZ.
26 сен 19, 15:12    [21979954]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
ivanra
Member

Откуда:
Сообщений: 860
WGA,

Вот, а теперь смотрим исходники своих методов, которые попали в этот стек, начиная с
автор
ru.septagon.recs.rs.view.CompanyFullView$InnerCashRegisterView.of

Судя по всему, там мега запросы к базе. Возможно, во время выполнения произошел редеплой. Как там работает в таких случаях хибернейт не знаю, но к запросам лучше приглядеться
26 сен 19, 15:12    [21979958]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
mayton
Member

Откуда: loopback
Сообщений: 42385
EhCache сбоку где-то прикручен? По eviction-policy еще не успел кеши зачистить и засрал весь хип.
26 сен 19, 15:17    [21979963]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7927
у нас дамп памяти вообще был замусорен byte[] массивами от Java JDBC был. Долго и нудно техподдерка Oracle предлагала JDBC проапгрейдить, потом выяснилось, что косяк в нашем коде. Не всегда statement.close вызывали, вот JDBC буфера в памяти и оставались. Самое веселое, что просмоторшики дампов данную память относили к категории "может быть очищена", в результате по версии просмоторшиков дампов вообще был бред 2 Gb heap, из них 1.8 Gb "может быть очищена", но упали с out of memory.
26 сен 19, 15:20    [21979967]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
ivanra
Member

Откуда:
Сообщений: 860
Leonid Kudryavtsev,

да, тут скорее всего ошибка в бизнес коде. Судя по названию метода CompanyFullView можно предположить, что происходил обход дерева подразделений, и что-то пошло не так. Например, цикл. Или проблема n+1
26 сен 19, 15:26    [21979976]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7927
WGA
|- <Java Local> org.postgresql.core.v3.QueryExecutorImpl @ 0x6e27c97b8 | 200 | 1,154,864
|- contextClassLoader org.jboss.modules.ModuleClassLoader @ 0x6e56718d8 | 88 | 141,432

Из-за редеплоя "просрали" classloader, из-за просранного класслоадера не смогли почистить не закрытые сессии/статменты?

как предположение
26 сен 19, 15:27    [21979978]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7927
ivanra
Leonid Kudryavtsev,

да, тут скорее всего ошибка в бизнес коде. Судя по названию метода CompanyFullView можно предположить, что происходил обход дерева подразделений, и что-то пошло не так. Например, цикл. Или проблема n+1

Leonid Kudryavtsev
|- contextClassLoader org.jboss.modules.ModuleClassLoader @ 0x6e56718d8 | 88 | 141,432

Если 88 это кол-во копий classLoader'а, то IMHO налицо классический bug с редиплоем

Как-то класлоадеров многовато, на мой взгляд.
26 сен 19, 15:29    [21979982]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7927
+ где-то в коде не закрываются сессии/стайтменты

одно наслоилось на другое, получилось 2 Gb мусора. Если бы открытых "жрущих" сессии/стайтментов не было бы, то рано или поздно уплали бы по классической out of perm gen (или метаспейс). А так, JDBC heap засисрает быстрее, чем классы perm gen

IMHO
26 сен 19, 15:33    [21979989]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
ivanra
Member

Откуда:
Сообщений: 860
Leonid Kudryavtsev,
кеш это обычно различные варианты HashMap-а, а тут ArrayList. Целый гиг данных, прочитанный из базы каким-то одним методом. Не так давно мы фильмы такого объема смотрели, для БД это многовато
26 сен 19, 15:42    [21980007]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7927
ivanra
кеш это обычно различные варианты HashMap-а, а тут ArrayList. Целый гиг данных, прочитанный из базы каким-то одним методом. Не так давно мы фильмы такого объема смотрели, для БД это многовато

Не правда ваша. В наше время программистам 2 Гига засрать - как 2 пальца обосновать ))) Банальные буффера для обмена по сети, для Oracle JDBC thin драйвера по 32-64 MB - запросто! Даже для простейшего "select dummy from dual" - дабы не жалко (при нормальной работе они реиспользуются и очищаются).

Здесь же видим 200 НЕ закрытых Statement'ов в 88 не до убитых копиях приложений (88 штук класслоадеров).
26 сен 19, 15:50    [21980018]     Ответить | Цитировать Сообщить модератору
 Re: Memory Leak?  [new]
WGA
Member

Откуда:
Сообщений: 392
mayton
|- [436] byte[26] @ 0x6f45318b0  2018-05-28 11:07:02.658117

Интересно. Строки сериализованы в байты для экономии. В ASCIIZ.
Это дата/время создания или обновления, есть в каждой сущности. И поля соответствующие типа LocalDateTime, а не строка.
mayton
EhCache сбоку где-то прикручен? По eviction-policy еще не успел кеши зачистить и засрал весь хип.
Нет, кэш второго уровня не подключен. Не дошло до этого.
Leonid Kudryavtsev
у нас дамп памяти вообще был замусорен byte[] массивами от Java JDBC был. Долго и нудно техподдерка Oracle предлагала JDBC проапгрейдить, потом выяснилось, что косяк в нашем коде. Не всегда statement.close вызывали, вот JDBC буфера в памяти и оставались. Самое веселое, что просмоторшики дампов данную память относили к категории "может быть очищена", в результате по версии просмоторшиков дампов вообще был бред 2 Gb heap, из них 1.8 Gb "может быть очищена", но упали с out of memory.
Невысвобождение ресурсов - не наш случай. Почти везде container-managed transaction managment, руками ничего не высвбождается. Специально проверил все бины с ручным управлением - там не используется JPA. А где JDBC просмотрел - все закрывается.
ivanra
WGA,

Вот, а теперь смотрим исходники своих методов, которые попали в этот стек, начиная с
автор
ru.septagon.recs.rs.view.CompanyFullView$InnerCashRegisterView.of

Судя по всему, там мега запросы к базе. Возможно, во время выполнения произошел редеплой. Как там работает в таких случаях хибернейт не знаю, но к запросам лучше приглядеться
Да, очень похоже на мега-граф объектов, тянущихся с главной сущностью Company. А возможно еще и косяки с equals/hashCode имеются.

Судя по куче разных объектов типа Currency с одним IDшником (тот самый RUB), возможно equals/hashCode работают некорректно и Hibernate не может понять, что это один и тот же объект и плодит их со страшной силой. Надо порядок в сущностях навести.

В общем ушел пытаться воспроизвести проблему в своей песочнице.
26 сен 19, 15:56    [21980025]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Java Ответить