Java.lang.OutOfMemoryError: пространство PermGen при использовании веб-приложений

Я борюсь с проблемой 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)

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

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

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

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

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

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

Ответ 5

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