Подтвердить что ты не робот

Обнаружение Кто создал тему (w. Eclipse)

Как узнать, кто создал Thread в Java?

Представьте следующее: вы используете ~ 30 сторонних JAR в сложной среде плагина. Вы запускаете его, запускаете много кода, делаете некоторые вычисления и, наконец, вызываете shutdown().

Этот жизненный цикл обычно работает отлично, за исключением того, что при каждом запуске некоторые (не-демонические) потоки остаются свисающими. Это не проблема, если каждое завершение работы было последним отключением, я мог бы просто запустить System.exit() в этом случае. Тем не менее, этот цикл может выполняться несколько раз, и он каждый раз увеличивает количество мусора.

Итак, что мне делать? Я вижу потоки в Eclipse Debug View. Я вижу их следы стека, но они не содержат никаких намеков на их происхождение. Нет трассировки стека создателя, нет отличимого имени класса, ничего.

Есть ли у кого-нибудь идея, как решить эту проблему?

4b9b3361

Ответ 1

Хорошо, я смог решить проблему (самостоятельно): я поставил точку останова в

Thread.start() 

и вручную выполнил каждое обращение. Таким образом, я довольно быстро обнаружил, что Class.forName() инициализировал много статического кода, который в свою очередь создал эти загадочные потоки.

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

Ответ 2

Я религиозно называю свои темы (используя Thread (Runnable, String), в противном случае они получат общий и несколько бесполезный имя. Сбрасывая потоки, вы узнаете, что работает и (тем самым), что их создало. Я не думаю, что это не решит создание сторонних потоков.

EDIT: бюллетень JavaSpecialist рассмотрел этот вопрос недавно (февраль 2015 г.) с помощью диспетчера безопасности. Подробнее см.

БОЛЬШЕ: пара деталей для использования метода JavaSpecialist: API SecurityManager включает в себя "checkAccess (newThreadBeingCreated)", который вызывается в потоке создателя потока. Новый поток уже имеет свое "имя", инициализированное. Таким образом, в этом методе у вас есть доступ как к потоку создателя потока, так и к новому, а также может записывать/печатать и т.д. Когда я это пробовал, проверяемый код начал бросать исключения для защиты доступа; Я исправил это, вызвав его под AccessController.doPriviledged(новый PrivilegedAction() {...}, где метод run() вызвал контролируемый код.

Ответ 3

При отладке вашего приложения Eclipse вы можете остановить весь поток, нажав org.eclipse.equinox.launcher.Main поле в отладочном представлении.

Затем оттуда для каждого потока вы можете увидеть трассировку стека и перейти к методу thred run.

Иногда это может помочь, а иногда и нет.

Как сказал Брайан, хорошая практика - назвать темы, потому что это единственный способ легко определить "кто их создал"

Ответ 4

К сожалению, это не так. В Eclipse я вижу все блокирующие потоки, но их трассировки стека отражают только их внутреннее состояние и (по-видимому) не раскрывают никакой информации о местоположении их создания. Кроме того, из внешнего вида объекта (с использованием представления Variables) мне не удалось выявить дальнейшие намеки.