Как проанализировать дамп потока java?
Я пытаюсь понять больше о java,особенно об управлении памятью и потоками. По этой причине я недавно нашел интерес к просмотру дампов потоков.
вот несколько строк, взятых из веб-приложения с помощью VisualVM, встроенного инструмента для java:
"Finalizer" daemon prio=8 tid=0x02b3d000 nid=0x898 in Object.wait() [0x02d0f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x27ef0288> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0x27ef0288> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
Locked ownable synchronizers:
- None
"Reference Handler" daemon prio=10 tid=0x02b3b800 nid=0x494 in Object.wait() [0x02cbf000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x27ef0310> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x27ef0310> (a java.lang.ref.Reference$Lock)
сначала у меня есть вопросы о некоторых именах переменных:
- что означает tid и nid?
- что такое фигура в квадратных скобках после Объект.ждать?
затем для самой трассировки стека:
- что это значит ждем (ява.ленг....) а какое число в
- что это значит заблокирован (ява.ленг....) тот же вопрос, что в
Я думал, что слово locked каким-то образом связано с условием ожидания, однако я ошибался. На самом деле, я интересно, почему locked повторяется три раза, но поток находится в работоспособном состоянии, как видно в том же дампе:
"Thread-0" prio=6 tid=0x02ee3800 nid=0xc1c runnable [0x03eaf000]
java.lang.Thread.State: RUNNABLE
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:199)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
- locked <0x23963378> (a java.io.BufferedInputStream)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
- locked <0x23968450> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
- locked <0x23968450> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at org.codehaus.plexus.util.cli.StreamPumper.run(StreamPumper.java:145)
и наконец, это было самое худшее из них:
"CompilerThread0" daemon prio=10 tid=0x02b81000 nid=0x698 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
этот поток находится в работоспособном состоянии, но он ждет при условии. Какое условие и что такое 0x00000?
почему трассировка стека настолько коротка без каких-либо доказательств класса потока?
Если бы вы могли ответить на все мои вопросы, я был бы очень благодарный.
спасибо
3 ответа:
TID-это идентификатор thead, а NID-это: собственный идентификатор потока. Этот идентификатор сильно зависит от платформы. Это NID в дампах потоков jstack. В Windows это просто идентификатор потока уровня ОС в процессе. В Linux и Solaris это PID потока (который, в свою очередь, является легким процессом). В Mac OS X это, как говорят, собственное значение pthread_t.
перейдите по этой ссылке: Java-уровня потока, ID: для определения и дальнейшего объяснения этих двух терминов.
на сайте IBM я нашел эту ссылку: как интерпретировать дамп потока. это охватывает это более подробно:
это объясняет, что означает это ожидание: Блокировка предотвращает доступ к общему ресурсу более чем одной сущности. Каждый объект в Java имеет соответствующий замок (полученные с помощью синхронизированного блока или метода). В случае JVM потоки конкурируют за различные ресурсы в JVM и блокируют объекты Java.
затем он описывает монитор как особый вид механизма блокировки, который используется в JVM для обеспечения гибкой синхронизации между потоками. Для целей этого раздела прочитайте термины монитор и блокировка взаимозаменяемо.
и дальше:
чтобы избежать наличия монитора на каждом объекте, JVM обычно использует флаг в блоке класса или метода, чтобы указать, что элемент заблокирован. Большую часть времени часть кода будет проходить через какой-то заблокированный раздел без разногласий. Таким образом, флаг guardian достаточно, чтобы защитить этот кусок кода. Это называется плоский монитор. Однако если другой поток хочет получить доступ к некоторому коду, который заблокирован, произошло подлинное противоречие. Теперь JVM должен создать (или раздуть) объект монитора для удержания второго потока и организовать механизм сигнализации для координации доступа к разделу кода. Этот монитор теперь называется надутым монитором.
вот более глубокое объяснение того, что вы есть видя на строках из дампа потока. Поток Java реализуется собственным потоком операционной системы. Каждый поток представлен жирным шрифтом, например:
"Thread-1" (TID: 0x9017A0, sys_thread_t:0x23EAC8, state:R, native ID: 0x6E4) prio=5
*следующие 6 пунктов объясняет это, как я сопоставил их из примера, значения в скобках []:
- имя [поток-1],
- идентификатор [ 0x9017A0],
- адрес структуры данных JVM [ 0x23EAC8],
- текущее состояние [R],
- идентификатор собственного потока [ 0x6E4],
- и приоритет [5].
"ожидание", по-видимому, является потоком демона, связанным с самим jvm, а не с потоком приложения perse. Когда вы получаете "в Объект.wait ()", что означает, что поток демона, "финализатор" здесь, ждет уведомления о блокировке объекта, в этом случае он показывает вам, какое уведомление он ждет: "- ожидание на (java.ленг.ссылка.Обнаруживаются$Замком)"
определение ReferenceQueue является: Очереди ссылок, к которым зарегистрированные ссылочные объекты добавляются сборщиком мусора после обнаружения соответствующих изменений достижимости.
финализатор поток выполняется так, что сборка мусора работает для очистки ресурсов, связанных с объектом. Если я вижу это правильно, финализатор не может получить блокировку этого объекта: java.ленг.ссылка.Обнаруживаются.удалить(обнаруживаются.java: 118) потому что объект java выполняет метод, поэтому поток финализатора блокируется до тех пор, пока этот объект не будет завершен с его текущей задачей.
кроме того, финализатор не просто хочет восстановить память, он более вовлечен в очистку ресурсы. Мне нужно больше изучить его, но если у вас есть открытые файлы, сокеты и т. д... связанные с методами объектов, то финализатор будет работать над освобождением этих элементов, а также.
что такое фигура в квадратных скобках после объекта.ждать в дамп нити?
это указатель в памяти на поток. Вот более подробное описание:
C. 4. 1 Информация О Потоке
первая часть потока раздел показывает поток, который вызвал фатальную ошибку, следующим образом:
Current thread (0x0805ac88): JavaThread "main" [_thread_in_native, id=21139] | | | | +-- ID | | | +------------- state | | +-------------------------- name | +------------------------------------ type +-------------------------------------------------- pointer
указатель потока-это указатель на внутреннюю структуру потока Java VM. Это, как правило, не представляет интереса, если вы не отлаживаете живую виртуальную машину Java или основной файл.
это последнее описание пришло из: руководство по устранению неполадок для Java SE 6 С HotSpot VM
вот еще несколько ссылок на дампы потока:
далее к превосходному ответу @James Drinkard:
обратите внимание, что в зависимости от базовой реализации, то java.ленг.Нитка.Государство о потоке, который заблокирован в собственном методе, можно сообщить как
RUNNABLE
, гдеA thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.
оказывается, что это описание также включает блокировку в вызове ОС, таком как опрос или операция чтения-предположительно потому, что нет никакой гарантии, что JVM может знать, когда собственный вызов метода заблокирован на уровне ОС.
многие обсуждения дампов потоков JVM, которые я видел, либо полностью игнорируют эту возможность, либо беспечно просматривают ее, не рассматривая последствия - не в последнюю очередь это то, что инструменты мониторинга могут смутно сообщать, что несколько таких потоков "работают", и, кроме того, что все они работают на 100%.
попробуйте http://fastthread.io
этого, вероятно, достаточно для многих случаев.