Сборка мусора синглетонов в сервлете - PullRequest
0 голосов
/ 03 мая 2018

Когда я использую синглтон в сервлете и класс синглтона создает ArrayList, например:

private static ArrayList<SessionData> mSessionData = new ArrayList<>();

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

1 Ответ

0 голосов
/ 03 мая 2018

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

Это не утечка памяти!

происходит утечка памяти при неправильном управлении компьютерной программой распределение памяти

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

Как вы управляете памятью, используя список массивов, зависит от вас. Если вы заполняете его объектами и никогда не очищаете их, это может вызвать утечку памяти, но это не будет связано с синглтоном. Поэтому, если вы сохраняете в своем массиве объекты SessionData, которые ссылаются на уже закрытые / неактивные сеансы, вы должны удалить их из списка (и позволить java в конечном итоге GC их). Обычно в веб-программировании управление сессиями может быть обработано для вас используемой платформой.

В контейнере сервлета каждый сервлет находится в отдельном контексте. Это главное для безопасности веб-приложения. Так что, если вы используете этот синглтон в разных приложениях / сервлетах, у каждого из них будет свой экземпляр. Эта инкапсуляция очень важна по нескольким причинам. Представьте, что вы создаете одноэлементный класс, и вредоносное программное обеспечение устанавливается в том же контейнере сервлета. Если они создают один и тот же класс и получают ваш экземпляр, они смогут прочитать ваши данные. И этого не должно случиться. Таким образом, каждый экземпляр сервлета будет иметь свой собственный экземпляр синглтона, и когда сервлет исчезнет, ​​экземпляр синглтона уйдет с ним.

Например, вы можете проверить здесь https://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html

Как работает загрузка классов Tomcat. Я считаю, что большинство контейнеров сервлетов работают именно так. Singleton может иметь два экземпляра, если его загружают разные загрузчики классов. Так в случае с котом:

  Bootstrap
      |
   System
      |
   Common
   /     \
Webapp1   Webapp2 ... 

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

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

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