java.lang.OutOfMemoryError: пространство PermGen при использовании веб-приложения - PullRequest
11 голосов
/ 21 февраля 2011

Я борюсь с проблемой outOfMemory PermGen, которая появилась недавно.Один из фрагментов журнала, который был сохранен при появлении ошибки:

java.lang.OutOfMemoryError: PermGen space
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
        at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.findClass(ModuleImpl.java:1872)
        at org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:720)
        at org.apache.felix.framework.ModuleImpl.access$300(ModuleImpl.java:73)
        at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1733)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

Я увеличил максимальный размер разрешений -XX:MaxPermGen=128m, но это только временное решение, потому что я уверен, что мы столкнулись с некоторой утечкой памяти здесь,Веб-часть наших приложений развернута на пристани (jsf + icefaces).Нажатие на случайные компоненты увеличивает используемую память - я отслеживаю ее с jstat -gcold, и почти каждое попадание означает на 3-4 КБ больше.Я добавил -XX:+TraceClassLoading в параметры jvm и вижу, как многие sun.reflect.GeneratedConstructorAccessor и sun.reflect.GeneratedMethodAccessor регистрируются, когда в веб-интерфейсе пользователя есть какие-либо действия.Я также сделал дамп кучи, когда использовался 99% пермгена.Я использовал профилировщик YourKit для анализа кучи.На вкладке загрузчик классов есть загрузки sun.reflect.DelegatingClassLoader строк с 1 классом для каждого.Что может быть причиной того, что память постоянно растет?Буду очень признателен за любую помощь.

Заранее спасибо, Лукаш

Ответы [ 5 ]

5 голосов
/ 09 января 2012

В Sun JVM отражательный доступ к свойствам и методам первоначально осуществляется путем вызова через JNI в реализацию JVM.Если JVM замечает, что метод или поле доступны посредством отражения, она сгенерирует байт-код, чтобы сделать то же самое - механизм, который он называет «инфляция».Это имеет начальную скорость удара, но после этого работает примерно в 20 раз быстрее.Большая победа, если вы много размышляете.

Этот байт-код находится в классах, созданных экземплярами DelegatingClassLoader, и занимает место permgen.Если это проблема, вы можете отключить инфляцию, установив системное свойство sun.reflect.inflationThreshold в 0 (ноль).

4 голосов
/ 21 февраля 2011

Прежде всего, это не имеет отношения к JSF.Вы просто предоставляете своему серверу приложений слишком мало памяти по сравнению с потребностями вашего веб-приложения.У вас будет такая же проблема со всеми остальными фреймворками, которые используют под прикрытием хороший рефлекс (подумайте обо всех этих разрешениях EL).Это может быть JSF, Wicket, Spring-MVC и даже обычный JSP / Servlet.Шанс больше только на компонентных веб-фреймворках, которые сильно зависят от распознавателей EL, таких как JSF (и другие).

Кроме того, известно, что серверы Tomcat (на основе) также могут вызывать это, когда вы (горячий)) перераспределять слишком часто.Пройдите по следующим ссылкам, чтобы узнать о нем и о том, как с ним бороться:

3 голосов
/ 21 февраля 2011

Я бы предложил использовать Eclipse MAT и следовать этому руководству, посвященному проблемам пермгена .

Хотя, как заметил Даффимо, вы проделали огромную работу по анализу проблемы, само происхождение проблем, похоже, до сих пор неизвестно. Может быть, это просто один из компонентов, какой-то парсер (как предлагает jwenting) или аналогичный. Проблема не обязательно означает, что вам нужно выбросить JSF из стека.

1 голос
/ 21 февраля 2011

Прежде всего, спасибо вам за то, что вы проделали такую ​​тщательную работу по расследованию этого вопроса и еще лучше по написанию вашего вопроса.Мир (и этот сайт) был бы лучше, если бы все были такими же талантливыми и такими же хорошими писателями, как и вы.

Я думаю, вы уже нашли ответ: я думаю, JSF и его использование рефлексииэто ваша проблема.

Это одна из причин, почему я избегаю JSF, как чумы.

На мой взгляд, JSF - неудачное расширение Struts.Я бы посоветовал пользовательский интерфейс HTML / CSS / JavaScript / AJAX быть таким же способным, как и JSF, если не больше, и гораздо менее обременительным для моей JVM.Пользовательский интерфейс вызывает службы и остается приятным и отделенным от серверной части.

0 голосов
/ 21 февраля 2011

Проблемы Permgen обычно вызваны тем, что какой-то процесс выполняет МНОГО операций String.intern (). В этом виноваты некоторые генераторы и парсеры XML / HTML. Посмотрите сначала, вы можете быстро ударить преступника.

...