Утечка памяти не выгружает Singletons при закрытии приложения Java EE - PullRequest
0 голосов
/ 01 января 2019

Это * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * '' '' * 1007 »* *1007* *1005* *1005* *1005* *1005* *1005* *1005* *» (*1007* "), а при отключении приложений Java EE» ( ") * * * * '' '.По всей видимости, загрузчик классов, который загрузил класс singleton, сохранит ссылку на класс, и, следовательно, экземпляр singleton никогда не будет собран.При развертывании нового экземпляра приложения обычно создается новый загрузчик классов, и прежний загрузчик классов будет продолжать существовать из-за синглтона.

1) Я не понимаю, как я могу« unload » синглтона и что означает «, закрывающее приложение Java EE ».Не могли бы вы предоставить примеры кода (неправильные и правильные примеры кода) и сценарии?

2) Из того же сообщения stackoverflow:

Возьмите любое веб-приложение, работающее влюбой контейнер сервлетов (Tomcat, Jetty, Glassfish, что угодно ...).Повторно развертывайте приложение 10 или 20 раз подряд (может быть достаточно просто прикоснуться к WAR в каталоге автоматического развертывания сервера.

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

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

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

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

Я не могу понять, как это возможно, что контейнер (классы / объекты Tomcat) содержит ссылки на объекты или классы моего приложения, и это моя вина.Автоматическое управление памятью означает, что мне не нужно заботиться об освобождении памяти, верно?Так о чем мне позаботиться, если мое приложение будет запущено в Tomcat или другом контейнере?

1 Ответ

0 голосов
/ 01 января 2019

Один jvm может использоваться как «сервер приложений».Он содержит контейнеры, входящие в «пакеты» (например, файлы EAR или WAR), которые можно динамически добавлять / удалять из jvm.

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

Или цитата из IBM :

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

По запросу от OP я попытался найти примеры для «плохих» и соответственно «работающих» одноэлементных реализаций, но я не смогне найти ни одного.

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

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