Найти тему

Моделирование и устранение заблокированных потоков в Kotlin [видео]

Оглавление

Поскольку мы продолжаем изучать моделирование и устранение проблем с производительностью в Kotlin, давайте обсудим, как заставить потоки переходить в состояние BLOCKED.

В этой последней статье серии о моделировании и устранении проблем с производительностью в Kotlin давайте обсудим, как перевести потоки в состояние BLOCKED. Поток войдет в BLOCKEDсостояние, если он не может получить блокировку объекта, потому что другой поток уже удерживает блокировку того же объекта и не освобождает ее.

Программа Kotlin BLOCKED Thread

Вот пример программы, которая переводит потоки в BLOCKEDсостояние.

package com.buggyapp
class BlockedApp {      
fun start() {        
println("BlockedApp:started")        
for (counter in 0..9) { // Launch 10 threads.            
AppThread().start()        
}      
    }   
}    
class AppThread : Thread() {      
override fun run() {        
AppObject.something      
}  
}    
object AppObject {      
@get:Synchronized      
val something: Unit        
get() {            
while (true) {              
try {                  
Thread.sleep(6000000.toLong())              
} catch (e: Exception) {              
}            
}        
}  
}    
fun main() {      
println(BlockedApp().start())  
}

Пример программы содержит BlockedAppкласс. У этого класса есть start()метод. В этом методе 10создаются новые потоки. В AppThreadклассе есть run()метод, который вызывает getSomething()метод на AppObject. В этом getSomething()методе поток постоянно находится в спящем режиме; т. е. поток снова и снова спит в течение 10 минут. Но если вы заметили, getSomething()это синхронизированный метод. Синхронизированные методы могут выполняться только одним потоком за раз. Если какой-либо другой поток попытается выполнить getSomething()метод, в то время как предыдущий поток все еще работает над ним, то новый поток будет помещен в состояние BLOCKED.

В этом случае для выполнения метода запускается 10 потоков getSomething(). Однако только один поток получит блокировку и выполнит этот метод. Остальные 9 потоков будут переведены в BLOCKEDсостояние.

ПРИМЕЧАНИЕ.  Если потоки находятся в BLOCKEDсостоянии в течение длительного времени, приложение может перестать отвечать на запросы.

Как диагностировать заблокированные темы

Вы можете диагностировать BLOCKEDпотоки вручную или автоматически.

Ручной подход

При ручном подходе в качестве первого шага необходимо захватить дампы потоков. Дамп потока показывает все потоки, находящиеся в памяти, и пути выполнения их кода. Вы можете захватить дамп потока, используя один из 8 вариантов, упомянутых здесь . Но важным критерием является то, что вам нужно захватить дамп потока прямо в момент возникновения проблемы (что может быть сложно сделать). После захвата дампа потока вам необходимо вручную импортировать дамп потока с рабочих серверов на локальный компьютер и проанализировать его с помощью инструментов анализа дампа потока, таких как fastThread или samurai .

Автоматизированный подход

С другой стороны, вы также можете использовать сценарий с открытым исходным кодом yCrash , который бы собирал 360-градусные данные (журнал GC, 3 снимка дампа потока, дамп кучи, netstat, iostat, vmstat, top, top -H и т. д.) сразу, как только проблема появляется в стеке приложений, и немедленно анализируйте их, чтобы создать отчет об анализе основных причин.

Мы использовали автоматизированный подход. Ниже приведен отчет об анализе основных причин, созданный инструментом yCrash, в котором указан источник проблемы.

yCrash сообщает о транзитивном графе зависимостей из 9 заблокированных потоков
yCrash сообщает о транзитивном графе зависимостей из 9 заблокированных потоков

yCrash выводит транзитивный граф зависимостей , показывающий, какие потоки получают BLOCKEDи кто их блокирует. На этом транзитивном графе вы можете видеть, что «Поток-0» блокирует 9 других потоков. Если вы нажмете на имена потоков на графике, вы увидите трассировку стека этого конкретного потока.

yCrash, сообщающий о трассировке стека 9 потоков, находящихся в состоянии BLOCKED.
yCrash, сообщающий о трассировке стека 9 потоков, находящихся в состоянии BLOCKED.

Вот снимок экрана, на котором показана трассировка стека 9 потоков, находящихся в состоянии, BLOCKEDа также указана трассировка стека, в которой они застряли. Из трассировки стека видно, что поток застрял в com.buggyapp.blockedapp.AppObject#getSomething()методе.

Имея эту информацию, можно легко определить основную причину BLOCKEDпотоков состояний.

видео

Чтобы увидеть визуальное прохождение этого поста, нажмите ниже:

#Открытый #Источник #Потоки #Состояния #Котлин #Язык #Программирования #Хаос #Инженерия