Выбор ответа Senior JVM: память, GC, загрузка классов обновлено

Утечка через ThreadLocal

Вопрос

Почему ThreadLocal в пуле потоков веб-сервера часто приводит к утечкам?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Потоки пула живут долго, и значение остаётся в ThreadLocalMap потока, пока не вызван remove(). Значение хранится в карте самого потока, ключ (ThreadLocal) в ней слабая ссылка, а значение сильная.

Варианты ответа

  1. Потоки пула живут долго, и значение остаётся в ThreadLocalMap потока, пока не вызван remove()правильный ответ
  2. ThreadLocal хранит значения в статической коллекции, которая никогда не чистится
  3. GC не умеет собирать объекты, созданные в других потоках
  4. ThreadLocal создаёт копию значения для каждого потока JVM, а не только для текущего

Разбор

Значение хранится в карте самого потока, ключ (ThreadLocal) в ней слабая ссылка, а значение сильная. Поток пула не умирает, поэтому значение живёт, пока его не перезапишут или не удалят, а при редеплое ещё и удерживает загрузчик классов приложения. Правило: try { tl.set(x); ... } finally { tl.remove(); }. Статической коллекции нет, копий для всех потоков тоже, а GC собирает объекты независимо от потока-создателя.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме