powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
25 сообщений из 26, страница 1 из 2
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38380183
Viktor Grafskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, я использую Netbeans и Tomcat. Последний регулярно, при редеплоях, выбрасывает "java.lang.OutOfMemoryError: PermGen space" и отказывается работать до последующего рестарта. Ошибка проявляется в версиях tomcat-7.0.32 и tomcat-7.0.42. Я пробовал найти решение в гугле, нашел, что необходимо задать Tomcat'у дополнительные ключи запуска -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled. К сожалению, для меня этот рецепт не работает. Также заметил одну особенность - если tomcat запущен в режиме Debug, ошибка проявляется быстрее, чем в обычном режиме. Если кто сталкивался и решил проблему, прошу подсказать. С уважением.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38380191
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viktor GrafskiyПоследний регулярно, при редеплоях, выбрасывает "java.lang.OutOfMemoryError: PermGen space" и отказывается работать до последующего рестарта.
Проблема известная. Статей валом:
https://www.google.com/search?q=Tomcat permgen leak detection
http://java.dzone.com/articles/memory-leak-protection-tomcat
http://wiki.apache.org/tomcat/MemoryLeakProtection

Viktor GrafskiyОшибка проявляется в версиях tomcat-7.0.32 и tomcat-7.0.42. Я пробовал найти решение в гугле, нашел, что необходимо задать Tomcat'у дополнительные ключи запуска -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled.

Не факт что эта опция работает с вашим типом GC
http://stackoverflow.com/a/3720052

Мне казалось в свежих версиях Java permgen собирается без дополнительных настроек.

Viktor GrafskiyК сожалению, для меня этот рецепт не работает.

Проблема скорее всего в классических утечках. Например JDBC. Как в проекте работа с драйвером устроена? Tomcat DataSource, наверное не используется?

Viktor GrafskiyТакже заметил одну особенность - если tomcat запущен в режиме Debug, ошибка проявляется быстрее, чем в обычном режиме.

Маловероятно. Но возможно NetBeans чего-то там инструментирует дополнительно.

Viktor GrafskiyЕсли кто сталкивался и решил проблему, прошу подсказать. С уважением.
Использовать профайлеры, которые позволяют смотреть классы в PermGen и обнаруживать утечку classloader-ов.
Использовать стандартные инструменты Tomcat для обнаружения утечек в PermGen.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38380405
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Цикл статей про утечки памяти - http://java.jiderhamn.se/2012/03/04/classloader-leaks-vi-this-means-war-leak-prevention-library/

Тамже ссылка на гитхаб - https://github.com/mjiderhamn/classloader-leak-prevention/blob/master/src/main/java/se/jiderhamn/classloader/leak/prevention/ClassLoaderLeakPreventor.java

Отсекает 90% утечек, мне у себя пришлось допилить только утечку в google guice и opensaml, потому что они довольно кастомные.
На данный момент 140 деплоев без рестарта сервера
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38380489
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо бы понимать что за ошибка и что к ней приводит.
Не хватает памяти в которой хранятся классы. Почему это может быть? Либо ее реально не хватает, либо какой-то класс лоадится многократно, либо ошибки jvm.

А класс, насколько помню, идентифицируется собственно классом и его лоадером. То есть один класс загруженый разными лодерами - это разные классы, которые жрут память, но дают одинаковый функционал.

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

ошибки jvm? К сожалению, бывают и они, но как правило заканчиваются sigseg-ами. Cпасает переход на другой дистрибутив и другую сборку jvm.

Анлодинг классов? ну хз, может в громадных приложениях где есть много больших редкоиспользуемых классов и да. "По нормальному" же, приложение может залоадить класс при запуске, а анлодить класс во время работы незачем. Т.е. если используется такая фича, то это скорей всего только потому что автор хотел разобраться с класслодерами, реальной же необходиомости в ней нет. Кроме того, если памяти мало и происходит частый анлодинг (с последующей загрузкой) - это все равно что линукс увести в своп. Насколько я понимаю, этот ваш анлодинг был придуман для такого режима использования: приложение запускается, отрабатывает, завершается. И так много раз и много разных приложений. У вас же, судя по всему, не этот случай, приложение одно.

Но это мое лично мнение, может я че-то не то сказал.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38380994
Viktor Grafskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо за ценные советы!
BlazkowiczПроблема скорее всего в классических утечках. Например JDBC. Как в проекте работа с драйвером устроена? Tomcat DataSource, наверное не используется?Да, не используется. В качестве ORM я использую eclipselink и инициализация EntityManager происходит при старте приложения в отдельном классе:
public class EMF implements ServletContextListener { }
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
@WebListener
public class EMF implements ServletContextListener {
    transient private static EntityManagerFactory emf;
    transient private static EntityManager em;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        emf = Persistence.createEntityManagerFactory("rso-pu");
        em = emf.createEntityManager();
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        em.close();
        emf.close();
    }

    public static EntityManager getEntityManager() {
        if (em == null) {
            throw new IllegalStateException("EntityManager was not initialized properly.");
        }

        return em;
    }
}

BlazkowiczИспользовать профайлеры, которые позволяют смотреть классы в PermGen и обнаруживать утечку classloader-ов.
Использовать стандартные инструменты Tomcat для обнаружения утечек в PermGen. Profiler показывает что данные утекают в HashMap, который используется MySql jdbc драйвером, это отражено на приложенном к посту файле.
забыл никЦикл статей про утечки памяти - http://java.jiderhamn.se/2012/03/04/classloader-leaks-vi-this-means-war-leak-prevention-library/ В пункте 5 "Common mistakes" указано, что не следует упаковывать драйвер JDBC в war файл, а вместо этого положить его в classpath контейнера, я так и сделал, ситуация на мой взгляд не изменилась. Больше ничего такого из списка Known Offenders в моем маленьком приложении вроде бы нет. P.S. статья классная, спасибо!
chabapokя бы действовал так. Сначала нужно попробовать тупо увеличить пермген. Если классов много, может им у вас реально не хватает памти. Если ошибка будет все равно, тогда искать класс который многократно лоадится, и что-то с ним делать.Я пробовал увеличить permgen, но это лишь ненадолго оттягивает появление ошибки. Классов в приложении мало.
chabapokошибки jvm? К сожалению, бывают и они, но как правило заканчиваются sigseg-ами. Cпасает переход на другой дистрибутив и другую сборку jvm.Я думаю, что в моем случае до ошибок JVM далеко :-)
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38381023
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viktor GrafskiyProfiler показывает что данные утекают в HashMap, который используется MySql jdbc драйвером, это отражено на приложенном к посту файле.
Не очень понял как это связано. И почему данные на картинке "утекают". Это же heap. Попробуйте так. Деплоите проект. Потом раздеплаиваете его. Ищете в профайлере какой-нибудь класс своего проекта, по ссылкам его ClassLoader и оттуда надо смотреть кто держит ссылки на ClassLoader , связаный с GC Roots.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38381093
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторВ пункте 5 "Common mistakes" указано, что не следует упаковывать драйвер JDBC в war файл, а вместо этого положить его в classpath контейнера, я так и сделал, ситуация на мой взгляд не изменилась. Больше ничего такого из списка Known Offenders в моем маленьком приложении вроде бы нет. P.S. статья классная, спасибо!

Вы конечно покопайтесь с профайлером, руками победить это все же тоже ценный опыт, но если время поджимает, крайне советую применить фильтр из предложенной статьи.

Ну и да, как советовал Blazkowicz. Сделайте деплой-редеплой(а лучше 2-3 раза) чтобы можно было проще выяснить текущий класслоадер и ищите GC Roots
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38381116
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viktor GrafskiyProfiler показывает что данные утекают в HashMap, который используется MySql jdbc драйвером, это отражено на приложенном к посту файле.

видимо, не закрываете корректно соединения. где-то там вам надо добавить некоторый finally в котором все позакрывать

Хотя, если ошибки с пермген, то вомзможно проблема в чем-то типа Class.forName("com.mysql.jdbc.Driver") Если эта хрень делается с разными класслодерами, да плюс вы не закрываете соединение и класс не выгружается корретно - весьма вероятно такое получить.

В этом случае если избавиться от многократного лоадинга классов, то все равно будет OutOfMem но уже не в пермген. Надо корректно закрывать соединения резултсеты и статементы.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38381126
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viktor Grafskiy,

Можете выложить .hprof после пары редеплоев. Будет время - посмотрю.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38381349
Viktor Grafskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczПопробуйте так. Деплоите проект. Потом раздеплаиваете его. Ищете в профайлере какой-нибудь класс своего проектаПопробовал сделать redeploy три раза и обнаружил, что с каждым циклом undeploy/deploy профайлер добавляет по одному классу из моего проекта. Т.е. три раза перезагрузил проект - получил три класса с одинаковыми именами в списке загруженных классов. Скриншот во вложении.

забыл никВы конечно покопайтесь с профайлером, руками победить это все же тоже ценный опыт, но если время поджимает, крайне советую применить фильтр из предложенной статьи.Обязательно попробую и буду держать на вооружении, не успел просто ещё.

chabapokвидимо, не закрываете корректно соединения. где-то там вам надо добавить некоторый finally в котором все позакрыватьЯ тоже так думал, но не могу найти, EntityManager закрывается автоматически с помощью Servlet-Context-Listener'а.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38381351
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viktor GrafskiyПопробовал сделать redeploy три раза и обнаружил, что с каждым циклом undeploy/deploy профайлер добавляет по одному классу из моего проекта. Т.е. три раза перезагрузил проект - получил три класса с одинаковыми именами в списке загруженных классов. Скриншот во вложении.
Ну, вот и подтвердился ClassLoader Leak. Теперь нужно найти ClassLoader этого класса, который был самый первый и уже должен был быть раздеплоен. И на нем правой кнопкой -> Find Nearest GC Root
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38381368
Viktor Grafskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczМожете выложить .hprof после пары редеплоев. Будет время - посмотрю.
По Вашему совету я сделал дамп, и попробовал найти GC Root, вроде бы указывает на незакрытое соединение с mysql'ем. Хотя не уверен, что нашел то что надо, сделал скриншот. Пока что сам дамп выложить не могу(у меня закрыты обменники, а выложить сюда - не позволяет размер).
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38381383
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот и нашелся зверюга
Первая пара ссылок из гугла по имени класса:
http://stackoverflow.com/questions/11872316/tomcat-guice-jdbc-memory-leak
http://bugs.mysql.com/bug.php?id=68556
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38381388
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правда, мне ещё не понятно почему этот класс связан именно с загрузчиком приложения. Похоже ваш PU таки каждый раз загружает драйвер заново в контексте приложения. Остаётся надеятся что он его выгружает при закрытии EMF.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38381512
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Утечку драйвера можно закрыть используя глобальный datasource, но тут наверно не поможет, так как по картинке видно, что в памяти остаются не только классы persistence слоя
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38381515
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraУтечку драйвера можно закрыть используя глобальный datasource
Возможно.

ivanra, но тут наверно не поможет, так как по картинке видно, что в памяти остаются не только классы persistence слоя
Эээ... классы остаются все, потому что ClassLoader не собран. А ClassLoader не может быть собран из-за одного как-того класса. Таким образом один класс, держит все классы приложения.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38382301
Viktor Grafskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я думаю, что мне удалось победить ошибку в MySQL connector. На сайте Oracle'а даны рекомендации по применению аж двух способов обхода этой проблемы:
1) Добавить магический ключ clearReferencesStopThreads="true" в META-INF/context.xml [у меня этот рецепт не заработал]
2) В класс реализующий ContextServletListener добавить следующий код:
public class MyServletContextListener implements ServletContextListener
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
import com.mysql.jdbc.AbandonedConnectionCleanupThread;
.....
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        try {
            AbandonedConnectionCleanupThread.shutdown();
        } catch (InterruptedException ex) {
            Logger.getLogger(EMF.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Но к сожалению,... :-) проблема с классами моего приложения продолжает существовать. После каждого undeploy'я классы остаются загруженными, причем каждый redeploy оставляет по одному дополнительному экземпляру, что в конечном итоге опять приводит к java.lang.OutOfMemoryError: PermGen space, разница только в том, что теперь при разборе дампа я не могу найти ни одной ссылки GC root, вместо этого я получаю сообщение "GC root not found" (использую профайлер встроенный в netBeans). Доказательства на скриншоте. Правильно ли я понимаю, если не удалось найти ссылку на GC root, значит объект готов к сборке?
забыл никкрайне советую применить фильтр https://github.com/mjiderhamn/classloader-leak-prevention/blob/master/src/main/java/se/jiderhamn/classloader/leak/prevention/ClassLoaderLeakPreventor.java Фильтр я подключил к приложению, вижу диагностические сообщения, которые валятся при старте и при останове приложения, но увы моя проблема остается.
Blazkowiczклассы остаются все, потому что ClassLoader не собран. А ClassLoader не может быть собран из-за одного как-того класса. Таким образом один класс, держит все классы приложения.Я думаю, что Вы правы, а вот как мне теперь найти какой класс держит класс-лоадер - не понимаю.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38382402
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Скиньте дамп. И еще раз - вам нужно найти класслоадер, и именно у него смотреть gc roots а не у каких то своих классов
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38382860
Viktor Grafskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл никСкиньте дамп. И еще раз - вам нужно найти класслоадер, и именно у него смотреть gc roots а не у каких то своих классовЯ Вам очень признателен. Ссылка на дамп http://yadi.sk/d/ByzcOFmM8Vysr .
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38382909
DEVcoach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Viktor Grafskiy ,
Вот старая каноничная статья, которая проливает свет на то, почему происходят мемори лики в permgen, и как с ними бороться http://frankkieviet.blogspot.ru/2006/10/classloader-leaks-dreaded-permgen-space.html
Настоятельно рекомендую к прочтению.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38382913
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще странно, на класслоадер есть только weak\soft\phantom ссылки, должен собираться.
Вечером внимательнее посмотрю
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38382920
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Меня вот это фигня смущает - org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLLexer.

Как вы работаете с энтити менеджером? Вы точно закрываете его?
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38382961
DEVcoach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, у вас косяк с JPA. Что-то где-то не закрываете. Что бы в этом убедиться, откройте дамп в VisualVM, потом перейдите в Classes, и запустите поиск по слову JPA. Потом отсортируйте результаты по количеству инстансов. Вы увидите, что у вас висит куча всякого барахла, которое ссылается на разные томкатовские класслоадеры.
А внутри каждого из 5-6 зависших класслоадеров болтается тот самый лексер, который упомянул забыл ник . А в каждом таком лексере сидят какие-то байты на 9Mb. Вот вам и лик.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38382965
Viktor Grafskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DEVcoachВот старая каноничная статья, которая проливает свет на то, почему происходят мемори лики в permgen, и как с ними бороться http://frankkieviet.blogspot.ru/2006/10/classloader-leaks-dreaded-permgen-space.html
Настоятельно рекомендую к прочтению. Спасибо Вам, уже сегодня её читал :-)

забыл никМеня вот это фигня смущает - org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLLexer.

Как вы работаете с энтити менеджером? Вы точно закрываете его?Зуб давать не буду, но я получаю ссылки на EntityManager через этот класс(смотрите под spoiler'ом), соответственно при останове приложения, EntityManagerFactory и EntityManager должны закрываться, и в отладчике я вижу, что метод contextDestroyed выполняется
public class EMF implements ServletContextListener
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
@WebListener
public class EMF implements ServletContextListener {
    transient private static EntityManagerFactory emf;
    transient private static EntityManager em;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        emf = Persistence.createEntityManagerFactory("rso-pu");
        em = emf.createEntityManager();
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        em.close();
        emf.close();
        try {
            AbandonedConnectionCleanupThread.shutdown();
        } catch (InterruptedException ex) {
            Logger.getLogger(EMF.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static EntityManager getEntityManager() {
        if (em == null) {
            throw new IllegalStateException("EntityManager was not initialized properly.");
        }

        return em;
    }
}

P.S. Я в данный момент, руководствуясь приведеной Вами статьей - http://java.jiderhamn.se/2012/03/04/classloader-leaks-vi-this-means-war-leak-prevention-library , пытаюсь понять где может быть проблема, но что то пока безуспешно.
...
Рейтинг: 0 / 0
Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
    #38382967
Viktor Grafskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DEVcoachДа, у вас косяк с JPA. Что-то где-то не закрываете. Что бы в этом убедиться, откройте дамп в VisualVM, потом перейдите в Classes, и запустите поиск по слову JPA. Потом отсортируйте результаты по количеству инстансов. Вы увидите, что у вас висит куча всякого барахла, которое ссылается на разные томкатовские класслоадеры.
А внутри каждого из 5-6 зависших класслоадеров болтается тот самый лексер, который упомянул забыл ник . А в каждом таком лексере сидят какие-то байты на 9Mb. Вот вам и лик.Спасибо, я попробую и отпишу.
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Tomcat регулярно выдает ошибку java.lang.OutOfMemoryError: PermGen space
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]