setContextClassLoader импликации - PullRequest
2 голосов
/ 03 марта 2011

Аналогично этому вопросу: Значения setContextClassLoader , я пытаюсь убрать предупреждения об утечках памяти.В частности, у меня есть сервлет с кодом следующим образом:

public void doGet(HttpServletRequest httpRequest, 
        HttpServletResponse httpResponse) throws ServletException, IOException {
    class BasicThread extends Thread {
        public void run() {
            // Do a finite amount of stuff here
        }
    }
    Thread thread = new BasicThread();
    //thread.setContextClassLoader(null);
    thread.start();
}

Эта статья: http://wiki.apache.org/tomcat/MemoryLeakProtection#cclThreadSpawnedByWebApp, указывает, что если я раскомментирую строку setContextClassLoader, то сообщения об ошибках исчезнут.

Но мой вопрос: есть ли утечка памяти?Если так, я не хочу просто убрать предупреждения, я хочу исправить утечку.Как мне это сделать?

Спасибо.

(также, если я поменяю строку "// Делаем здесь конечное количество вещей" на "// Делаем бесконечным количество вещей здесь (т. Е. Цикл навсегда) ", тогда каков правильный способ избежать утечек памяти в этом сценарии?)

Ответы [ 2 ]

2 голосов
/ 03 марта 2011

Это реальная проблема, только если верно следующее.1. Поток никогда не останавливается, если поток никогда не останавливается, корня GC нет, и ClassLoader никогда не может быть подвергнут сборке мусора.2. Ваше приложение выполняет «горячее» развертывание, поэтому вы обязательно должны принять это во внимание.

Основная проблема заключается в том, что, когда вы хотите развернуть и повторно развернуть, сервер приложений захочет собрать загрузчик классов WAR,Если WAR создал поток, строго ссылающийся на загрузчик классов WAR, и поток не завершил, classlodaer никогда не сможет собрать мусор, и в конечном итоге вы увидите нехватку памяти: Permagen.

Если вы перезапустите свой сервер (иJVM) для каждого развертывания проблема не проявлялась.

Я прочитал статью, которую вы опубликовали, и они точно описывают то, что я предложил

SEVERE: кажется, что веб-приложение запущенопоток с именем [leakingThread], но не смог остановить его.Это может привести к утечке памяти.

Для большей справки я задал аналогичный вопрос относительно утечек в загрузчиках классов.

1 голос
/ 03 марта 2011

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...