Как выглядит дамп потока, когда JVM провел время в GC - PullRequest
4 голосов
/ 07 декабря 2011

При профилировании Java-приложения я отмечаю интересный факт.Когда JVM находится в GC, спираль дампов смерти выглядит так:

"1304802943@qtp-393978767-9985" prio=10 tid=0x00007f3ed02dd000 nid=0x74e7 in Object.wait() [0x000000004febb000]
 java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:626)
    - locked <0x00000007aed40048> (a org.mortbay.thread.QueuedThreadPool$PoolThread)

"26774405@qtp-393978767-9984" prio=10 tid=0x00007f3ee4b37000 nid=0x74e6 in Object.wait() [0x0000000045d1a000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:626)
    - locked <0x00000007aed83aa0> (a org.mortbay.thread.QueuedThreadPool$PoolThread)

"764808089@qtp-393978767-9983" prio=10 tid=0x00007f3ee4c50000 nid=0x74e5 in Object.wait() [0x000000004ad6a000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:626)
    - locked <0x00000007aed5c448> (a org.mortbay.thread.QueuedThreadPool$PoolThread)

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

Это поведение имеет какое-то отношение к ГХ, или это просто совпадение?

Ответы [ 3 ]

3 голосов
/ 29 декабря 2012

Отвечая только на заголовок вопроса:

Как выглядит дамп потока, когда JVM проводит время в GC?

Ответ: у вас нет средств для получениятакой дамп (обычным способом).

JVM обрабатывает запрос на дамп потока только после достижения безопасной точки , чего просто не может быть в GC.

Но естьэто чит-способ получить дамп потока активного GC с помощью недокументированной JVMTI-функции AsyncGetCallTrace, которая упоминается в этом посте:

http://jeremymanson.blogspot.com/2010/07/why-many-profilers-have-serious.html

Также намекает, что Oracle Solaris Studio можно использовать для получения таких смешанных дампов нативных / Java-потоков.

1 голос
/ 30 декабря 2011

Попробуйте jmap -histo: жить во времени, вы можете сравнить вывод, посмотреть, какие типы объектов растут.

Вам необходимо установить JDK для jmap.http://docs.oracle.com/javase/6/docs/technotes/tools/share/jmap.html

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

0 голосов
/ 07 декабря 2011

Полагаю, у вас есть пул потоков, который ждет, чтобы что-то сделать.Если ваш процесс эффективен и у вас есть даже 100 запросов в секунду, у вас могут возникнуть проблемы с перехватом даже одного потока, выполняющего что-то.Я предлагаю вам посмотреть на загрузку процессора вашего процесса.Если он равен 50%, у вас есть 50% шанс обнаружить, что один поток (возможно, не поток запросов) что-то делает.

Если вы хотите посмотреть, на что тратит время ваш сервер, я бы попробовал такой профилировщик, какVisualVM, или коммерческий профилировщик, например, YourKit.

При поиске в Google вашего кода, я нашел другую версию http://grepcode.com/file/repo1.maven.org/maven2/org.mortbay.jetty/jetty-util/7.0.0.pre5/org/mortbay/thread/QueuedThreadPool.java, но я подозреваю, что в этом блоке используются темы TIMED_WAIT в методе run ()

                // We are idle
                // wait for a dispatched job
                synchronized (this)
                {
                    if (_job==null)
                        this.wait(getMaxIdleTimeMs());
                    job=_job;
                    _job=null;
                }
...