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

JSF 2.2 Потребление памяти: почему Mojarra сохраняет ViewScoped Beans из последних 25 просмотров в памяти?

Память за сеанс растет

Мы испытываем высокое потребление памяти при использовании JSF 2.2 (2.2.12) с Mojarra. После исследования наших нагрузочных тестов выяснилось, что размер данных в наших компонентах ViewScoped Beans довольно велик (иногда более 1 МБ). В любом случае - при переходе от представления к представлению размер памяти сеанса увеличивается и увеличивается. Мы не можем уменьшить размер bean-компонентов в краткосрочной перспективе, поэтому такое поведение оказывает некоторое влияние.

Решение 1 - Изменение параметров контекста (не работает)

Теперь - мы поиграли с официальным параметром контекста от Mojarra, который по умолчанию установлен в 15:

com.sun.faces.numberOfLogicalViews
com.sun.faces.numberOfViewsInSession

Изменение этих параметров на более низкое значение не повлияло на потребление памяти в наших нагрузочных тестах.

Решение 2 - Изменение activeViewMapsSize (работает)

Мы отлаживали Mojarra и нашли следующий код в ViewScopeManager:

Integer size = (Integer) sessionMap.get(ACTIVE_VIEW_MAPS_SIZE);
if (size == null) {
    size = 25;
}

По умолчанию размер для хранения последних посещенных представлений равен 25. Видя это, мы реализовали Session Listener, который устанавливает это значение равным 1:

public class SetActiveViewMapsSizeSessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent event) {
        event.getSession().setAttribute(ViewScopeManager.ACTIVE_VIEW_MAPS_SIZE, 1);
    }
}

Это очевидно сработало. Память перестала расти, так как сохраняется только 1 просмотр.

Так почему 25 просмотров в памяти?

Таким образом, Mojarra хранит историю 25 представлений в памяти, если не определено другое значение в сеансе. Я не могу найти документацию по этому поводу. Может кто-нибудь объяснить, для чего это нужно? Это для браузера назад? На наших страницах JSF отключено кэширование. Так что браузер обратно всегда будет создавать новый вид. Это не должно быть проблемой для нас.

Решение 2 - верный подход? Может ли кто-нибудь объяснить недостатки этого подхода?

Обновление 1

После различных комментариев и более глубокой отладки выяснилось, что:

  • com.sun.faces.numberOfLogicalViews определяет размер logicViewMap, в котором хранится только (!) состояние дерева компонентов пользовательского интерфейса.
  • com.sun.faces.application.view.activeViewMapsSize определяет размер activeViewMap, который содержит компоненты ViewScoped.

При изменении numberOfLogicalViews на 1, mojarra будет по-прежнему отслеживать все bean-объекты области видимости из последних 25 представлений. Когда вы настраиваете его наоборот - numberOfLogicalViews в 15 и activeViewMapsSize в 1 - представление не может быть правильно инициализировано из-за отсутствия данных, я полагаю. Мы даже не получили исключения. Я хотел бы понять, почему mojarra решила установить activeViewMapsSize выше, чем numberOfLogicalViews а не так, поскольку мы хотим настроить потребление памяти без непредсказуемого поведения.

Обновление 2

Мы создали проблему в Мохарре: JAVASERVERFACES-4015.

4b9b3361