Стоит ли чистить ThreadLocals в Filter для решения проблем, связанных с пулом потоков? - PullRequest
14 голосов
/ 20 февраля 2011

Короче говоря - tomcat использует пул потоков, поэтому потоки используются повторно. Некоторые библиотеки используют переменные ThreadLocal, но не очищают их (используя .remove()), поэтому фактически они возвращают "грязные" потоки в пул.

У Tomcat есть новые функции обнаружения этих вещей при завершении работы и очистки локальных потоков. Но это означает, что потоки «грязные» в течение всего выполнения.

Что я могу сделать, это реализовать Filter, и сразу после завершения запроса (и возврата потока в пул) очистить все ThreadLocal s, используя код из tomcat ( метод там называется checkThreadLocalsForLeaks).

Вопрос в том, стоит ли это того? Два плюса:

  • предотвращение утечек памяти
  • предотвращение недетерминированного поведения библиотек, которые предполагают, что поток "свежий"

Один минус:

  • Решение использует отражение, поэтому оно потенциально медленное. Все данные отражения (Field с), конечно, будут кэшироваться, но все же.

Другой вариант - сообщить о проблеме библиотекам, которые не очищают свои локальные потоки.

Ответы [ 3 ]

6 голосов
/ 20 февраля 2011

Я бы пошел по пути сообщения о проблеме разработчикам библиотеки по 2 причинам:

  • Это поможет другим людям, которые хотят использовать ту же библиотеку, но не имеют навыков / времени.чтобы найти такую ​​УЖАСНУЮ утечку памяти.
  • Чтобы помочь разработчикам библиотеки создать лучший продукт.

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

В качестве примечания, я не возражаю против включения этого фильтра в среде разработки / тестирования и регистрации критической ошибки, если переменная ThreadLocal все еще присоединена.

1 голос
/ 20 февраля 2011

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

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

Я бы не слишком беспокоился о производительности. Медленный бит в отражении - это поиск метаданных; как только у вас есть объект Field, то его использование довольно быстрое и становится быстрее со временем - AIUI начинает работать с выполнения собственного вызова в JVM, но после некоторого числа использований генерирует байт-код для доступа, который затем может быть скомпилирован в собственный код, оптимизирован, встроен и т. д., поэтому он не должен быть намного медленнее, чем прямой доступ к полю. Я не думаю, что код Tomcat повторно использует объекты Field в запросах, поэтому, если вы хотите воспользоваться этим, вам придется написать собственный код очистки. В любом случае стоимость производительности будет намного меньше, чем стоимость ввода-вывода, связанного с запросом.

1 голос
/ 20 февраля 2011

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

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