как это возможно, 3 потока находятся в заблокированном состоянии, ожидая одного и того же монитора, и нет ни одного потока, принадлежащего этому монитору - PullRequest
1 голос
/ 12 августа 2011

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

У вас есть какое-нибудь разумное объяснение этой позиции?

Вот заблокированные темы;

"pool-1013-thread-5" prio = 7 tid = 600000000842be00 nid = 17280 lwp_id = 518677 ожидает входа в монитор [9fffffffe6aff000..9fffffffe6b00bd0] java.lang.Thread.State: ЗАБЛОКИРОВАН (на мониторе объекта) в org.apache.log4j.Category.callAppenders (Category.java:201) - ожидает блокировки <9ffffffde1e7ec88> (a org.apache.log4j.spi.RootLogger) в org.apache.log4j.Category.forcedLog (Category.java:388) в org.apache.log4j.Category.log (Category.java:853) в org.slf4j.impl.Log4jLoggerAdapter.debug (Log4jLoggerAdapter.java:173) в org.hibernate.jdbc.AbstractBatcher.logOpenResults (AbstractBatcher.java:426) в org.hibernate.jdbc.AbstractBatcher.getResultSet (AbstractBatcher.java:210) в org.hibernate.loader.Loader.getResultSet (Loader.java:1808)

"pool-1013-thread-4" prio = 7 tid = 6000000008413400 nid = 17279 lwp_id = 518676 ожидает входа в монитор [9fffffffe6eff000..9fffffffe6f00b50] java.lang.Thread.State: ЗАБЛОКИРОВАН (на мониторе объекта) в org.apache.log4j.Category.callAppenders (Category.java:201) - ожидает блокировки <9ffffffde1e7ec88> (a org.apache.log4j.spi.RootLogger) в org.apache.log4j.Category.forcedLog (Category.java:388) в org.apache.log4j.Category.log (Category.java:853) в org.slf4j.impl.Log4jLoggerAdapter.debug (Log4jLoggerAdapter.java:173) в org.hibernate.loader.Loader.getRow (Loader.java:1197) в org.hibernate.loader.Loader.getRowFromResultSet (Loader.java:603) в org.hibernate.loader.Loader.doQuery (Loader.java:724) в org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections (Loader.java:259) в org.hibernate.loader.Loader.loadEntity (Loader.java:1881) в org.hibernate.loader.entity.AbstractEntityLoader.load (AbstractEntityLoader.java:71) в org.hibernate.loader.entity.AbstractEntityLoader.load (AbstractEntityLoader.java:65) в org.hibernate.persister.entity.AbstractEntityPersister.load (AbstractEntityPersister.java:3072) в org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource (DefaultLoadEventListener.java:434) в org.hibernate.event.def.DefaultLoadEventListener.doLoad (DefaultLoadEventListener.java:415) в org.hibernate.event.def.DefaultLoadEventListener.load (DefaultLoadEventListener.java:165) в org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad (DefaultLoadEventListener.java:223) в org.hibernate.event.def.DefaultLoadEventListener.onLoad (DefaultLoadEventListener.java:126) в org.hibernate.impl.SessionImpl.fireLoad (SessionImpl.java:905)

"pool-1013-thread-3" prio = 7 tid = 6000000008411c00 nid = 17278 lwp_id = 518675 ожидает записи монитора [9fffffffe70ff000..9fffffffe7100ad0] java.lang.Thread.State: ЗАБЛОКИРОВАН (на мониторе объекта) в org.apache.log4j.Category.callAppenders (Category.java:201) - ожидает блокировки <9ffffffde1e7ec88> (a org.apache.log4j.spi.RootLogger) в org.apache.log4j.Category.forcedLog (Category.java:388) в org.apache.log4j.Category.log (Category.java:853) в org.slf4j.impl.Log4jLoggerAdapter.debug (Log4jLoggerAdapter.java:173) в org.hibernate.jdbc.AbstractBatcher.logOpenResults (AbstractBatcher.java:426) в org.hibernate.jdbc.AbstractBatcher.getResultSet (AbstractBatcher.java:210) в org.hibernate.loader.Loader.getResultSet (Loader.java:1808) в org.hibernate.loader.Loader.doQuery (Loader.java:697)

Ответы [ 3 ]

7 голосов
/ 12 августа 2011

Сначала я подозревал, что объект Lock наконец не разблокируется. Но потом я посмотрел на предоставленные вами дампы двух потоков.

Действительно 3 потока заблокированы на одной и той же блокировке, а именно это Log4J, Категория класс. Согласно дампу потока, это код, на котором они все заблокированы:

for(Category c = this; c != null; c=c.parent) {
  synchronized(c) {  // LOCKED HERE
    if(c.aai != null) {
      writes += c.aai.appendLoopOnAppenders(event);
    }
    if(!c.additive) {
      break;
    }
  }
}

TDA подтверждает, что ни один другой поток не имеет этой блокировки, но также предоставляет очень полезный совет:

Этот монитор не имеет потока, блокирующего его. Это означает, что поток VM удерживает его. Если вы видите, что на многих мониторах нет блокирующих потоков, это обычно означает, что сборщик мусора работает. В этом случае вы должны рассмотреть анализ вывода сборщика мусора. Если в дампе много мониторов без блокирующего потока, щелчок по узлу дампа даст вам дополнительную информацию.

и далее:

Этот дамп потока содержит мониторы без информации о потоке блокировки. Это означает, что монитор удерживается системным потоком или каким-либо внешним ресурсом. Вы должны проверить мониторы без блокировки потоков для получения дополнительной информации.

Заключение : вы должны включить ведение журнала сбора мусора и посмотреть, не является ли это основной причиной. Также проверьте, не делаете ли вы или какая-либо библиотека что-то странное с Log4J (круговые категории?) - просто дикая догадка. Полезные опции:

-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:gc.log
1 голос
/ 10 января 2014

Я столкнулся с очень похожей проблемой.Я полагаю, что это связано с https://issues.apache.org/bugzilla/show_bug.cgi?id=50614

В вашем случае я бы предложил использовать jstack -l, а затем проанализировать фактические заблокированные объекты из стека (их адреса отличаются от адресов монитора) - так для каждого«в ожидании блокировки X» вы должны найти «- заблокированный X» в стеке некоторого потока (при печати с использованием jstack -l).

В моем случае я обнаружил, что поток-виновник (удерживающий блокировку) был фактически заблокирован при сбросе записи приложения Console (и оставался таковым, хотя трассировка стека говорит, что он находится в состоянии выполнения).Я тоже не смог найти тупиковую петлю.

Так что, по крайней мере, один из способов решения этой проблемы - это внутренняя блокировка в ОС, которая запускается через консольный сброс записи.Поэтому простое исправление состоит в том, чтобы устранить консольный лог-приложение (или повысить его уровень).

0 голосов
/ 09 марта 2014

Это немного, когда я использовал log4j SocketAppender для записи через сокет в logstash.

SocketAppender блокирует, и когда с другой стороны отправляется событие в logstash, и logstash не может его обработать (т. Е. Блокируется при вызовеasticsearch), тогда ваше приложение будет блокироваться.

Любые другие потоки, которые пытаются войти в систему, используя этот appender, будут просто сидеть и ждать в этом заблокированном состоянии, вставленном в дамп потока.

Лучший способ обойти это - использовать async appender.

Смотрите здесь для получения дополнительной информации: Как работает SocketAppender

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