Как заставить JSF убрать своего государственного менеджера?

В частности, это AjaxStateManager в Richfaces 3.1.HomeMadePatch/JSF1.1. Я не несу ответственности за эти технологические решения, и я уже читал соответствующие вопросы, такие как 1, 2, 3, которые в основном советуют обновить версии или перейти на JSF без состояния, что я был бы очень рад сделать, если смогу, но из-за большая огромность приложения, я боюсь, я не могу этого сделать.

Возвращаясь к теме, я сейчас пытаюсь оптимизировать потребление кучи памяти. Поскольку мои предшественники устанавливали область действия сеанса почти для каждого компонента и устанавливали тайм-аут сервера на 6 часов (с некоторым обновлением javascript до его истечения в браузере), пользователи имеют очень длинные сеансы и продолжают накапливать память. Я сделал некоторую оптимизацию самостоятельно (ну, это своего рода имитация объема разговора: при попадании на несколько страниц я очищаю все в основных компонентах). Теперь, когда пользователи возвращаются на главную страницу, их сессия весит около 300 КБ, в следующем виде:

  • AjaxStateManager $ SynchronizedStateHolder: 280 КБ
  • Другие объекты в сессии: 20kb

Эти результаты были получены путем создания heapdump и анализа памяти с помощью Eclipse MAT. Как видите, 93% памяти Ajax поддерживает бесполезные состояния. Я хочу заставить его освободить эти бесполезные состояния. Любая идея о том, как это сделать?

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

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

1 ответ

Решение

Хорошо, так что на всякий случай, вот соответствующая ссылка о проблеме, в основном говоря, что нет решения, потому что оно присуще механизмам JSF. Я прибег к использованию параметра step для количества просмотров, которое кажется более чистым.

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

package com.mycompany.ajaxutils;

import javax.faces.application.StateManager;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;

import org.ajax4jsf.application.AjaxStateManager;
import org.ajax4jsf.util.LRUMap;

public class AjaxStateHelper {
    private static final AjaxSateManagerUncover asmu = new AjaxSateManagerUncover(null);

    public static void cleanAjaxStateManager() {
        HttpSession currentSession = (HttpSession) FacesContext.getCurrentInstance().getExternalContext()
                .getSession(false);
        LRUMap lrumap = asmu.getLRUMap(currentSession.getAttribute(AjaxStateManager.class.getName()
                + ".VIEW_STATES_MAP"));
        lrumap.clear();
    }

    /**
     * This inner class is needed because we need to make a cast to a SynchronizedStateHolder
     * which is an inner protected class inside AjaxStateManager
     */
    protected static class AjaxSateManagerUncover extends AjaxStateManager {

        public AjaxSateManagerUncover(StateManager parent) {
            super(parent);
        }

        public LRUMap getLRUMap(Object stateMap) {
            SynchronizedStateHolder s = (SynchronizedStateHolder) stateMap;
            return s.getStateMap();
        }
    }
}

Просто позвони AjaxStateHelper.cleanAjaxStateManager(); откуда угодно в приложении, и это освободит память для вас. Но остерегайтесь потенциальных побочных эффектов, это экспериментальный код

Другие вопросы по тегам