Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

Основная причина для java.lang.OutOfMemoryError: Metaspace:

  • слишком много классов или
  • слишком большие классы загружаются в 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.

Javaassist в Maven repo.

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

Ответ 2

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

Изменить: В теории вы также можете быть уверены, что постоянно создаете прокси.