TGViewer
Библиотека джависта | Java, Spring, Maven, Hibernate Библиотека джависта | Java, Spring, Maven, Hibernate @javaproglib · 22K subscribers
Post #7801 2.74K
❌ ThreadLocal + Virtual Threads = утечка памяти

Если вы перешли на virtual threads, но продолжаете использовать ThreadLocal, то у вас проблема, которая пока просто не выстрелила.

ThreadLocal хранит данные в ThreadLocalMap — по одной map на каждый тред. Когда тредов было 200 в пуле, это было терпимо. Когда виртуальных тредов сотни тысяч, каждый несёт свою map, и heap начинает гореть. Плюс мутабельность: ThreadLocal.set() в глубоком call stack — это неявное состояние, которое легко забыть почистить через .remove(). В try-finally это работает до первого необработанного исключения.

Java 21 предлагает замену — ScopedValue.

🔹 Ключевые отличия

ScopedValue.where(TENANT_ID, tenant).run(() -> { ... }) — значение привязано к scope, а не к треду. Вышли из блока и значение автоматически недоступно. Никакого .remove(), никакого «забыл почистить».

Иммутабельность по дизайну. Нельзя сделать .set(). Если нужно другое значение, создаёте вложенный scope. Это убирает целый класс багов с «протеканием» контекста между запросами.

Легковесность. Внутри массив вместо HashMap. При масштабе в 100k+ тредов разница в потреблении памяти ощутимая.

Работает в связке со StructuredTaskScope: дочерние виртуальные треды автоматически наследуют scoped values родителя. Не нужно вручную пробрасывать контекст.

Практический вывод: если вы мигрируете на virtual threads, аудит ThreadLocal — обязательный шаг. ScopedValue пока preview, но API стабилизируется, и направление очевидно. Как минимум стоит уже сейчас заменить ThreadLocal на ReentrantLock-protected shared state или ScopedValue там, где передаёте tenant ID, request context, trace ID и подобные per-request данные.

══════ Навигация ══════
Вакансии • Задачи • Собесы

🐸 Библиотека джависта

#CoreJava
  • 👍 9
  • ❤ 1
  • 🔥 1
  • 🎉 1
More from @javaproglib
  1. Oct 10, 2026Post #7892
  2. Oct 10, 2026Read. Write. Edit. Bash. Это базовый набор операций Pi — агента, на котором построен OpenC…
  3. Oct 2, 2026🎹 Что делать после ChatGPT? Следующий шаг — AI-агенты. Они не просто отвечают на запросы,…
  4. Sep 30, 2026🔥 Последний день для разработчиков AI уже пишет код. Теперь важнее научиться встраивать е…
  5. Sep 30, 2026🫡 Шпаргалка по аннотациям Spring Boot @Autowired, @RestController, @Transactional, @Cache…
  6. Sep 29, 2026🤩 В Java для стека лучше использовать Deque Если нужен обычный LIFO — «последним пришёл,…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →