2013-05-28 5 views
8

Пытается отладить ошибочную Java-виртуальную машину. Этот процесс представляет собой большую виртуальную машину (кучу 100 Гбайт), на которой работает Sun VM 1.6u24 на Centos 5, которая выполняет обычную операционную работу, то есть доступ к базе данных, ввод/вывод файлов и т. Д.JVM периодически висит

После того как процесс был перезапущен для обновления версии программного обеспечения, мы заметили, что его пропускная способность значительно снизилась. В большинстве случаев топ-отчет о том, что процесс Java полностью использует 2 ядра. В течение этого времени виртуальная машина полностью не отвечает: никаких журналов не записывается и не реагирует на внешние инструменты, такие как jstack или kill -3. Как только VM восстанавливается, процесс продолжается, как обычно, до следующего зависания.

strace показывает, что во время этих зависаний только 2 потока выполняют системные вызовы. Это были потоки VM «VM Thread» (21776) и «Периодическая задача задачи VM» (21786). Предположительно, эти 2 потока используют процессорное время. Иногда потоки приложений пробуждаются и выполняют свою работу. В остальное время они, кажется, ждут на разных фьютексах. Кстати, первая строка нормальной фазы всегда является SIGSEGV.

[pid 21776] sched_yield()    = 0 
[pid 21776] sched_yield()    = 0 
[pid 21776] sched_yield(<unfinished ...> 
[pid 21786] <... futex resumed>)  = -1 ETIMEDOUT (Connection timed out) 
[pid 21776] <... sched_yield resumed>) = 0 
[pid 21786] futex(0x2aabac71ef28, FUTEX_WAKE_PRIVATE, 1 <unfinished ...> 
[pid 21776] sched_yield(<unfinished ...> 
[pid 21786] <... futex resumed>)  = 0 
[pid 21786] clock_gettime(CLOCK_MONOTONIC, {517080, 280918033}) = 0 
[pid 21786] clock_gettime(CLOCK_REALTIME, {1369750039, 794028000}) = 0 
[pid 21786] futex(0x2aabb81b94c4, FUTEX_WAIT_PRIVATE, 1, {0, 49923000} <unfinished ...> 
[pid 21776] <... sched_yield resumed>) = 0 
[pid 21776] sched_yield()    = 0 
[pid 21776] sched_yield()    = 0 
[pid 21955] --- SIGSEGV (Segmentation fault) @ 0 (0) --- 
[pid 21955] rt_sigreturn(0x2b1cde2f54ad <unfinished ...> 

Проблема проявляется на двух разных серверах. Откат нашей версии кода работал только на одном из двух серверов. Сообщения об ошибках не сообщались в системных журналах, а другой процесс Java на пораженной машине ведет себя правильно.

Этого следующий вывод был получен с gstack и показывает 2 типичных приложения ожидания тема:

Thread 552 (Thread 0x4935f940 (LWP 21906)): 
#0 0x00000030b040ae00 in [email protected]@GLIBC_2.3.2() from /lib64/libpthread.so.0 
#1 0x00002b1cdd8548d6 in os::PlatformEvent::park(long)() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#2 0x00002b1cdd92b230 in ObjectMonitor::wait(long, bool, Thread*)() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#3 0x00002b1cdd928853 in ObjectSynchronizer::wait(Handle, long, Thread*)() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#4 0x00002b1cdd69b716 in JVM_MonitorWait() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#5 0x00002b1cde193cc8 in ??() 
#6 0x00002b1ce2552d90 in ??() 
#7 0x00002b1cdd84fc23 in os::javaTimeMillis()() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#8 0x00002b1cde188a82 in ??() 
#9 0x0000000000000000 in ??() 
Thread 551 (Thread 0x49460940 (LWP 21907)): 
#0 0x00000030b040ab99 in [email protected]@GLIBC_2.3.2() from /lib64/libpthread.so.0 
#1 0x00002b1cdd854d6f in Parker::park(bool, long)() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#2 0x00002b1cdd98a1c8 in Unsafe_Park() from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so 
#3 0x00002b1cde193cc8 in ??() 
#4 0x000000004945f798 in ??() 
#5 0x00002b1cde188a82 in ??() 
#6 0x0000000000000000 in ??() 

Мы рассматривали проблемы с NTPD, в то числе секундных ошибок, но предложенные методы обход не помогли, ни делали, используя внешних NTPD-серверов. Перезагрузка машины сама по себе не помогла. У нас включен протокол GC, и он не выглядит проблемой GC, так как сообщений об этом нет. Если вы ищете какие-либо предложения, которые могут помочь в этом вопросе, любая помощь очень ценится.

+1

Может быть, что «GC pause»? Вы проверили алгоритм GC, который используется? http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html#0.0.0.%20The%20Concurrent%20Low%20Pause%20Collector%7Coutline – kosa

+0

Я согласен с @Nambari - я видели очень длинные паузы в больших JVM, когда они находятся под нагрузкой. Если процесс GC не может завершиться в разумные сроки, вы можете получить ошибку в памяти. Должна ли ваша JVM быть такой большой? –

+0

Чем больше куча, тем больше объектов нужно разрешить процессом GC. –

ответ

3

Вот несколько вещей, которые я хотел бы посмотреть на:

  • Когда виртуальная машина не отвечает на запросы, использовать iostat и vmstat, чтобы увидеть, если система обмолота. Это может произойти, когда вы перераспределяете память; т. е. ваша общая система использует значительно большую виртуальную память, чем физическая память.

  • Включите ведение журнала GC JVM и проверьте, не существует ли корреляции между JVM, идущим без ответа и GC работает.