Ошибка памяти Java - jmap не показывает классы, но jstat делает
Я устраняю странную утечку памяти. Это специфично для Java8, чего не происходит на 7u79.
У меня нет доступа к Java-коду.
Я точно знаю, какое действие пользователя вызывает утечку, я знаю, что утечка связана с классами (а не с кучей), а классы-нарушения легко обнаружить с помощью + TraceClassLoading + TraceClassUnloading:
[Loaded com.mastercard.mcwallet.sdk.xml.allservices.ShoppingCartRequest$JaxbAccessorF_oAuthToken from __JVM_DefineClass__]
[Loaded com.mastercard.mcwallet.sdk.... thousand similar classes per one user action... ]
Эти классы, по-видимому, увеличивают вывод счетчика классов на jstat -class
:
Loaded Bytes Unloaded Bytes Time
14045 26138.8 0 0.0 110.00 << buggy user action
14675 26754.6 0 0.0 110.05
15300 27364.9 0 0.0 110.10
15304 27370.9 0 0.0 110.11
15304 27370.9 0 0.0 110.11
15304 27370.9 0 0.0 110.11
15306 27374.0 0 0.0 110.11
15306 27374.0 0 0.0 110.11
15306 27374.0 0 0.0 110.11
15306 27374.0 0 0.0 110.11 << buggy user action
15930 27982.2 0 0.0 110.18
16553 28589.3 0 0.0 110.23
16553 28589.3 0 0.0 110.23
Дело в том, что эти классы никогда не собираются с мусором из metaspace, никогда [Unloaded]
, и они не отображаются в jmap -clstats
. Команда сообщает о более низком числе классов, число не увеличивается, нет подозрительных загрузчиков классов:
class_loader classes bytes parent_loader alive? type
<bootstrap> 2574 4493256 null live <internal>
0x0000000087d016d0 1 1471 0x000000008237f088 dead sun/reflect/[email protected]
... some lines omitted ...
0x000000008237f088 6505 12228227 0x0000000080383938 dead org/apache/catalina/loader/[email protected]
... some lines omitted ...
total = 600 14002 25351427 N/A alive=1, dead=599 N/A
Означает ли это звонок какой-либо звонок или дает какие-либо советы, которые я могу передать программистам? Они говорят, что не могут найти утечку. Могу ли я остановить эту утечку, просто используя функции JVM?
Ответы
Ответ 1
Я предполагаю, что JaxB загружает классы в вашу память, которые не собираются в мусор. Metaspace не будет выгружаться, если классы не будут выгружены.
Проверьте проблему JaxB для Java 8. Я думаю, вы можете избавиться от этого исключения, заменив версию api зависимостей или переключившись на дополнительный параметр:
-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true
Ответ 2
Если багги-классы недоступны для разгрузки, то они должны быть кэшированы где-то в приложении, и, насколько я понимаю, ваша цель - найти, где она находится, и предоставить эту информацию разработчикам.
Вы можете попробовать использовать Eclipse Memory Analyzer (MAT) для проверки вашего кучи кучи, и он может отображать проблемные области, классы и экземпляры, которые имеют ссылки на багги-классы.