использование памяти однокомпонентного дерева - PullRequest
2 голосов
/ 30 января 2011

Привет,

У меня есть приложение с обогащенными лицами (3.3.2.SR1). Приложение использует ModelPanel для просмотра объектов. Все модальные панели не отображаются, пока я не хочу показать их (rendered = false). Приложение становится большим и использует много связей от одной панели к другим. Все работает нормально, но похоже, что richfaces создает дерево UIComponent в памяти для всех возможных случаев, если компонент rendred имеет значение true или false. Когда я попытался проверить использование памяти приложением (я использовал YourKit Java Profiler для этих нужд), я вижу, что оно использует много памяти для одного сеанса.

Я использую Facelets вместе с richfaces, и я пытался использовать

<c:if test="rendred condition"... /> content </c:if>

Он начинает использовать значительно меньше памяти, но ... когда я перерисовываю область с панелью, элементы управления на родительском экране перестают работать. Я подозреваю, что это происходит из-за того, что каждый раз, когда дерево компонентов изменяется, оно воссоздает все дерево, и у меня есть несинхронизированные части клиента (html) и сервера (Faces).

Может кто-нибудь подсказать мне, как уменьшить использование памяти? У меня есть реальная проблема с этим, так как объект StandardSession в HeapMemory использует 60-150Mb. И почти вся эта память используется для UIControls.

Пример проблемы:

У меня есть страница, на которой есть ссылки на панель1, панель2, панель3.

Панель это:

<rich:modalPanel >
    <a4j:outputPanel layout="block" 
             rendered="#{PanelBeanHolder.renderedViewScreen}">
        <ui:insert name="panelContent" />
    </a4j:outputPanel>
</rich:modalPanel>

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

Заранее спасибо.

P.S. Я попытался сделать следующее, чтобы улучшить ситуацию

Настройка количества просмотров в сеансе внутри web.xml с помощью:

<context-param>
    <param-name>com.sun.faces.numberOfViewsInSession</param-name>
    <param-value>4</param-value>
</context-param>

<context-param>
    <param-name>com.sun.faces.numberOfLogicalViews</param-name>
    <param-value>4</param-value>
</context-param>

Это должно улучшить объект StateHolder, но это не очень помогает. Я сделал измерения и использование памяти растет, когда эти числа растут. Но когда мне надоело устанавливать их на 1,1 - некоторые страницы перестали работать. Иногда запрос перенаправляется на страницу приветствия. 2,2 улучшил ситуацию, но проблема с переадресацией на страницы приветствия все еще возникает.

Пытался использовать режим клиента в javax.faces.STATE_SAVING_METHOD . Он все еще использует много памяти для модели UIComponent. Даже если объекты сериализованы и должны храниться в форме.

Пытался переписать stateManager в faces.config:

<state-manager>org.ajax4jsf.application.CompressAjaxStateManager</state-manager>

и переписать buildViewState и restoreView для сжатия потока. Это не очень помогает.

1 Ответ

3 голосов
/ 30 января 2011

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

Настройка параметров сохранения состояния

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

Вы можете сохранить состояние в формах, используя параметр javax.faces.STATE_SAVING_METHOD. Тем не менее, имейте в виду, что вы отправляете больше информации по запросу, и существуют риски для безопасности, позволяющие клиенту определять состояние на стороне сервера (убедитесь, что вы довольны тем, как ваша реализация шифрует эти данные). Вам нужно будет проверить совместимость с вашими библиотеками компонентов (например, RichFaces), особенно если вы используете AJAX.

JSF 2 использует новый механизм сохранения состояния, который уменьшает накладные расходы сеанса; Ваш faces-config.xml должен быть обновлен до версии 2.0. Я полагаю, что эта идея пришла от Apache Тринидад , поэтому вы можете извлечь из нее версию, предшествующую JSF 2.

Создайте свое собственное сохранение состояния и / или создайте представление

Реализация ваших собственных StateManager и / или ViewHandler позволяет вам программно управлять обработкой представлений. Например, вы можете написать StateManager, который сохранил представления в базе данных (с соответствующим временем ожидания и очистки).

Использовать привязку компонентов и переходные элементы управления

Вы можете программно контролировать процесс создания компонентов. Из спецификации на переплет:

  • Когда экземпляр компонента создается впервые (обычно из-за ссылки UIComponentELTag на странице JSP), реализация JSF извлечет ValueExpression для привязки имени и вызовет getValue() для него. Если этот вызов возвращает ненулевое значение UIComponent (поскольку JavaBean уже программно создан и настроен компонент), этот экземпляр будет добавлен в создаваемое дерево компонентов. Если вызов возвращает значение NULL, будет создан новый экземпляр компонента, добавлен в дерево компонентов, и на ValueExpression будет вызван setValue() (что приведет к установке свойства в JavaBean для вновь созданного экземпляра компонента ).
  • Когда дерево компонентов воссоздается на этапе восстановления представления жизненного цикла обработки запросов, для каждого компонента, имеющего ValueExpression, связанный с именем «binding», будет вызываться setValue(), передавая воссозданный компонент экземпляр.

Возможно, вы могли бы использовать это со свойством transient на дочерних элементах, чтобы программно контролировать создание / уничтожение дочерних компонентов. Это руководство и немного грязно, но может работать в крайних случаях.

Я уверен, что это не исчерпывающий список.

...