Как диагностировать утечку метапространства Java 8?

У меня есть J2EE-приложение с интересным поведением... кажется, что куча ведет себя хорошо, увеличиваясь и уменьшаясь с помощью сборок мусора, как и ожидалось, с течением времени. Нет заметного общего долгосрочного расширения кучи. Однако метапространство продолжает неуклонно расти со скоростью около 20 МБ в час, пока мы не достигнем MaxMetaspace и не столкнемся с OOME. Я пробовал как параллельные сборщики мусора, так и сборщики мусора G1 (jdk1.8.0_40).

Приложение не развертывается повторно во время выполнения, поэтому не похоже, что это типичная утечка загрузчика классов. У кого-нибудь есть предложения, как отследить источник этой утечки?


person It Worked Yesterday    schedule 02.04.2015    source источник
comment
Вы уже нашли ответ на это?   -  person Ricardo Mogg    schedule 11.08.2015
comment
Можете ли вы предоставить дополнительную информацию: сервер JEE, используемые библиотеки.   -  person sibnick    schedule 17.08.2015
comment
Это была попытка запустить устаревшее приложение J2EE на JBoss 4.2.3.GA под Java 8. Это не поддерживаемая конфигурация, но клиент действительно хотел ее попробовать. Я знаю, что с тех пор в загрузке классов JBoss произошли серьезные изменения, поэтому я подозреваю, что это проблема с загрузчиком классов. Догадка Филиппа ниже относительно генерации прокси может иметь некоторые основания. В конце концов мы решили стиснуть зубы и портировать приложение на Wildfly 8.   -  person It Worked Yesterday    schedule 19.08.2015
comment
Я также столкнулся с подобной проблемой, мы используем wildfly 10, после нескольких повторных развертываний приложения Metaspace oom выдается ошибка. Увеличение максимального метапространства — это всего лишь обходной путь, а не решение. Я еще не нашел решения.   -  person Dmitry Avgustis    schedule 24.03.2017


Ответы (2)


Основная причина ошибки java.lang.OutOfMemoryError: Metaspace:

  • либо слишком много классов, либо
  • слишком большие классы загружаются в метапространство.

Если вы хотите воссоздать проблему, используйте этот фрагмент кода:

public class Metaspace {
static javassist.ClassPool cp = javassist.ClassPool.getDefault();

public static void main(String[] args) throws Exception {
    for (int i = 0; ; i++) { 
        Class c = cp.makeClass("eu.plumbr.demo.Generated" + i).toClass();
    }
  }
}

Все эти сгенерированные определения классов в конечном итоге потребляют Metaspace.

Помощник по Java в репозитории Maven.

Вы можете найти гораздо больше о OOME здесь

person Karol Król    schedule 12.08.2015
comment
Здравствуйте, у меня возникли проблемы с очисткой объекта javassist.ClassPool. Как это делается? - person Grayden Hormes; 28.03.2019

Сделайте дамп кучи и проанализируйте его с помощью Eclipse MAT. Посмотрите на классы, которые вы загрузили. Проверьте, есть ли что-то неожиданное, особенно повторяющиеся классы. Он также имеет проводник загрузчика классов.

Редактировать: Теоретически вы также можете постоянно генерировать прокси.

person Philippe Marschall    schedule 18.08.2015
comment
Мы попробовали проводник загрузчика классов MAT. К сожалению, приложение загружено и достаточно сложно, а утечка была достаточно медленной, чтобы оно все еще было иголкой в ​​стоге сена. Эта конфигурация в любом случае была задумана как временное решение, и мы достигли точки убывающей отдачи, поэтому мы сдались. - person It Worked Yesterday; 19.08.2015
comment
Я не знаю о проблеме с WildFly. OP никогда не отлаживал проблему, так что это могло быть что угодно, включая его / ее приложение. - person Philippe Marschall; 29.08.2017