Назад | Перейти на главную страницу

Выявление взаимоблокировок потоков в WebSphere

В WebSphere 8.5.5.13 у меня возникают ошибки из-за нехватки памяти, и количество подключений к базе данных исчерпывается. Мне кажется, что это связано с нехваткой потоков (у меня есть некоторые процессы, которые пытаются что-то сделать с таймаутом в 10 секунд, а другие задачи обычно занимают ~ 200 мс, что на самом деле занимает ~ 10200 мс). Но я думаю, что последний может даже оказаться в тупике. У меня есть ~ 100 потоков, ожидающих этого

3XMTHREADINFO      "WorkManager.DefaultWorkManager : 648" J9VMThread:0x000000000F2AA300, omrthread_t:0x00007FE38D060D78, java/lang/Thread:0x000000018ACD99E8, state:B, prio=5
3XMJAVALTHREAD            (java/lang/Thread getId:0x68C86, isDaemon:true)
3XMTHREADINFO1            (native thread ID:0xF8DE, native priority:0x5, native policy:UNKNOWN, vmstate:B, vm thread flags:0x00000201)
3XMTHREADINFO2            (native stack address range from:0x00007FE09C92F000, to:0x00007FE09C96F000, size:0x40000)
3XMCPUTIME               CPU usage total: 2.131995383 secs, current category="Application"
3XMTHREADBLOCK     Blocked on: com/ibm/ws/util/ThreadPool@0x000000011CD4B888 Owned by: "WorkManager.DefaultWorkManager : 689" (J9VMThread:0x00000000011B3000, java/lang/Thread:0x00000001B148B9A8)
3XMHEAPALLOC             Heap bytes allocated since last GC cycle=0 (0x0)
3XMTHREADINFO3           Java callstack:
4XESTACKTRACE                at com/ibm/ws/util/ThreadPool.getTask(ThreadPool.java:1083(Compiled Code))
4XESTACKTRACE                at com/ibm/ws/util/ThreadPool$Worker.run(ThreadPool.java:1916(Compiled Code))

и стек WorkManager.DefaultWorkManager: 689 выглядит так

3XMTHREADINFO      "WorkManager.DefaultWorkManager : 689" J9VMThread:0x00000000011B3000, omrthread_t:0x00007FE1A41A70D0, java/lang/Thread:0x00000001B148B9A8, state:R, prio=5
3XMJAVALTHREAD            (java/lang/Thread getId:0x68CCD, isDaemon:true)
3XMTHREADINFO1            (native thread ID:0x11410, native priority:0x5, native policy:UNKNOWN, vmstate:CW, vm thread flags:0x00001001)
3XMTHREADINFO2            (native stack address range from:0x00007FE1EFF3E000, to:0x00007FE1EFF7E000, size:0x40000)
3XMCPUTIME               CPU usage total: 1.663139688 secs, current category="Application"
3XMHEAPALLOC             Heap bytes allocated since last GC cycle=0 (0x0)
3XMTHREADINFO3           Java callstack:
4XESTACKTRACE                at java/lang/ThreadLocal$ThreadLocalMap.set(ThreadLocal.java:502(Compiled Code))
4XESTACKTRACE                at java/lang/ThreadLocal$ThreadLocalMap.access$100(ThreadLocal.java:311(Compiled Code))
4XESTACKTRACE                at java/lang/ThreadLocal.setInitialValue(ThreadLocal.java:197(Compiled Code))
4XESTACKTRACE                at java/lang/ThreadLocal.get(ThreadLocal.java:183(Compiled Code))
4XESTACKTRACE                at com/ibm/ws/util/objectpool/TwoTierObjectPool.purgeThreadLocal(TwoTierObjectPool.java:264(Compiled Code))
4XESTACKTRACE                at com/ibm/ws/buffermgmt/impl/WsByteBufferPool.purgeThreadLocal(WsByteBufferPool.java:173(Compiled Code))
4XESTACKTRACE                at com/ibm/ws/buffermgmt/impl/WsByteBufferPoolManagerImpl.purgeThreadLocals(WsByteBufferPoolManagerImpl.java:1169(Compiled Code))
4XESTACKTRACE                at com/ibm/ws/runtime/component/WSBBPoolListener.threadDestroyed(WSBBPoolListener.java:62(Compiled Code))
4XESTACKTRACE                at com/ibm/ws/runtime/component/ThreadPoolMgrImpl.threadDestroyed(ThreadPoolMgrImpl.java:459(Compiled Code))
4XESTACKTRACE                at com/ibm/ws/util/ThreadPool.fireThreadDestroyed(ThreadPool.java:1593(Compiled Code))
4XESTACKTRACE                at com/ibm/ws/util/ThreadPool.workerDone(ThreadPool.java:1005(Compiled Code))
5XESTACKTRACE                   (entered lock: com/ibm/ws/util/ThreadPool@0x000000011CD4B888, entry count: 1)
4XESTACKTRACE                at com/ibm/ws/util/ThreadPool$Worker.run(ThreadPool.java:1929(Compiled Code))

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

  at sun/misc/Unsafe.park(Native Method)
  at java/util/concurrent/locks/LockSupport.parkNanos(LockSupport.java:222)
  at java/util/concurrent/locks/AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2127)
  at com/ibm/ws/util/BoundedBuffer$GetQueueLock.await(BoundedBuffer.java:285)
  at com/ibm/ws/util/BoundedBuffer.waitGet_(BoundedBuffer.java:424)
  at com/ibm/ws/util/BoundedBuffer.take(BoundedBuffer.java:817)
  at com/ibm/ws/util/ThreadPool.getTask(ThreadPool.java:934)
  at com/ibm/ws/util/ThreadPool$Worker.run(ThreadPool.java:1704)

или

  at java/lang/Object.wait(Native Method)
  at java/lang/Object.wait(Object.java:231)
  at com/ibm/ws/util/BoundedBuffer.waitGet_(BoundedBuffer.java:192)
  at com/ibm/ws/util/BoundedBuffer.take(BoundedBuffer.java:543)
  at com/ibm/ws/util/ThreadPool.getTask(ThreadPool.java:819)
  at com/ibm/ws/util/ThreadPool$Worker.run(ThreadPool.java:1544)

и ни один из моих не похож на них.

Спасибо!

Общий пример тупика:

  • поток 1 содержит ресурс A и нуждается в ресурсе B для продолжения
  • поток 2 содержит ресурс B и нуждается в ресурсе A для продолжения

В этом сценарии ни один поток не может добиться прогресса, следовательно, существует тупик.

Опубликованные вами фрагменты не соответствуют этому шаблону, поэтому я не думаю, что это тупик.

С оговоркой, что я не знаком с конкретным кодом, показанным в опубликованных фрагментах, мне кажется, что первый показанный поток просто ожидает получения задачи из очереди WorkManager, которая, вероятно, пуста.

Также, кстати, в дампе потока Java IBM (из которого выглядят ваши фрагменты), тупиковые потоки обнаруживаются в процессе создания дампа и помечаются маркером DEADLOCK. Таким образом, вы можете найти это в дампе потока Java, чтобы сэкономить время, необходимое для сопоставления всех возможных комбинаций потока / ресурсов для поиска тупиковой ситуации вручную.

Надеюсь это поможет.