Есть ли способ закрыть все ThreadLocals (сохранение объекта Session) в методе contextDestroyed (), используя ContextListener во время завершения работы? - PullRequest
0 голосов
/ 26 сентября 2019

Я сталкиваюсь с утечкой памяти (TOMCAT v9) в моем приложении относительно объекта Threadlocals, как показано ниже:

25-Sep-2019 17: 40: 34.752 SEVERE [Thread-10] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks Веб-приложение [] создало ThreadLocal с ключом типа [java.lang.ThreadLocal] (значение [java.lang.ThreadLocal@7c606bab]) и значением типа [org.hibernate.internal.SessionImpl] (значение [SessionImpl (56310373)])), но не удалось удалить его при остановке веб-приложения.Потоки будут обновляться с течением времени, чтобы попытаться избежать возможной утечки памяти.

Я пытался закрыть объект сеанса каждый раз, когда мы открывали объект сеанса, но из-за отсутствия стандартов, используемых в кодировке i.Я сталкиваюсь с различными исключениями уровня Hibernate, поскольку некоторые объекты лениво выбираются, и закрытие сеанса приводит к неожиданным исключениям.

Теперь я пытаюсь добиться того же с помощью contextListener, если это возможно, не беспокоясь о закрытии каждого из них.объект сеанса.

Я пытался использовать System.gc (), но он не освобождает эти объекты ThreadLocal.

Не могли бы вы предложить какой-нибудь способ избавиться от этих объектов во время выключения?с помощью Listener или любым другим возможным способом?

1 Ответ

1 голос
/ 26 сентября 2019

После завершения веб-запроса вы должны закрыть сеанс Hibernate и удалить его из ThreadLocal.

Поскольку у вас возникают проблемы с отложенной загрузкой при генерации ответа (JSP?), Вынужно сделать это после ответ был полностью сгенерирован.

Вы можете сделать это в сервлете Filter.Убедитесь, что это перед любыми другими вашими фильтрами, поэтому сеанс закрывается как последний шаг.

public final class SessionCloseFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void destroy() {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        try {
            chain.doFilter(request, response);
        } finally {
            try {
                // Close and remove session here
            } catch (Exception e) {
                // Log but don't throw the exception
            }
        }
    }

}

...