Недавно мы перенесли ряд приложений из под управлением RedHat linux JDK1.6.0_03 в Solaris 10u8 JDK1.6.0_16 (гораздо более высокие спецификации), и мы заметили, что это довольно сложная проблема: при определенных нагрузках наши JVM попадают в "Спираль смерти" и, в конечном счете, теряют память. Что следует отметить:
- это не случай утечки памяти. Это приложения, которые работают очень хорошо (в одном случае более 3 лет), а ошибки из-за памяти в любом случае не уверены. Иногда приложения работают, иногда они не
- это не мы переходим к 64-разрядной VM - мы все еще запускаем 32-битный
- В одном случае использование последнего сборщика мусора G1 на 1.6.0_18, похоже, решило проблему. В другом, откат назад до 1.6.0_03 работал
- Иногда наши приложения падают с ошибками HotSpot
SIGSEGV
- Это влияет на приложения, написанные на Java, а также на Scala
Самый важный момент заключается в следующем: поведение проявляется в тех приложениях, которые внезапно получают поток данных (обычно через TCP). Это как если бы VM решает продолжать добавлять больше данных (возможно, переходить к TG), а не запускать GC в "пространстве новостей", пока не поймет, что он должен делать полный GC, а затем, несмотря на то, что практически все на VM является мусором, он как-то решает не собирать его!
Звучит безумно, но я просто не понимаю, что еще. Как еще вы можете объяснить приложение, которое одна минута падает с максимальной кучей 1Gb, а следующая работает просто отлично (никогда не происходит около 256 миллионов, когда приложение делает то же самое)
Итак, мои вопросы:
- Кто-нибудь еще наблюдал подобное поведение?
- есть ли какие-либо предложения относительно того, как я могу отлаживать сам JVM (в отличие от моего приложения)? Как доказать, что это проблема с VM?
- Есть ли там форумы VM-специалиста, где я могу попросить авторов VM (если они не находятся на SO)? (У нас нет контракта на поддержку)
- Если это ошибка в последних версиях виртуальной машины, почему никто ее не заметил?