Приложение, которое мы недавно начали время от времени сбой, с сообщением о «java.lang.OutOfMemoryError: запрошено 8589934608 байт для Chunk :: new. Нет свободного места?».
Я посмотрел вокругв сети и везде предложения ограничены
- возвратом к предыдущей версии Java
- скриптом с настройками памяти
- использование клиента вместо режима сервера
Возвращение к предыдущей версии означает, что в новой Java есть ошибка, но я не видел никаких признаков этого.Память не проблема вообще;на сервере доступно 32 ГБ, а для Xmx установлено значение 20, а для Xms - 10. Я не вижу, чтобы JVM исчерпала оставшиеся 12 ГБ (за вычетом суммы, выделенной нескольким другим процессам на машине).И мы застряли в режиме сервера из-за природы приложения и среды.
Когда я смотрю на использование памяти и ЦП для приложения, я вижу постоянное использование памяти в течение всего дня, но затем внезапнопрямо перед смертью загрузка ЦП возрастает до 100%, а использование памяти изменяется от Х до Х + 2 ГБ, до Х + 4 ГБ, до (иногда) Х + 8 ГБ до смерти JVM.Может показаться, что в JIT-компиляции происходит цикл повторного изменения размера массива.
Я уже видел, что ошибка возникает с запросом 8GB выше, а также с запросами 16GB.Когда это происходит, метод компиляции всегда один и тот же.Это простой метод, который имеет не вложенные циклы, не имеет рекурсии и использует методы для объектов, которые возвращают статические поля-члены или поля-члены экземпляра напрямую без малейших вычислений.
Итак, у меня есть 2 вопроса:
- Есть ли у кого-нибудь какие-либо предложения?
- Могу ли я проверить, есть ли проблема при компиляции этого конкретного метода в тестовой среде, без запуска всего приложения и непосредственного вызова компилятора JIT?Или я должен запустить приложение и сказать ему, чтобы он компилировал методы после гораздо меньшего числа вызовов (например, 2), чтобы заставить его компилировать метод почти мгновенно, а не в случайную точку дня?
@ StephenC
JVM - 1.6.0_20 (ранее 1.6.0_0), работающая на Solaris.Я знаю, что компиляция вызывает проблему по нескольким причинам.
ps
в секундах, предшествующих этому, показывает, что поток Java с идентификатором, соответствующим потоку компилятора (из jstack)занимает 100% процессорного времени jstack
показывает, что проблема в JavaThread "CompilerThread1" daemon [_thread_in_native, id=34, ...]
Метод, упомянутый в jstack
, всегда один и тот же итот, который мы написали.Если вы посмотрите пример вывода jstack
, вы поймете, что я имею в виду, но по понятным причинам я не могу предоставить примеры кода или имена файлов.Я скажу, что это очень простой метод.Essentiall несколько пустых проверок, 2 для циклов, которые делают проверки на равенство и, возможно, присваивают значения, и некоторые простые вызовы методов после.Всего может быть 40 строк кода.
Эта проблема возникала 2 раза за 2 недели, хотя приложение запускается каждый день и перезапускается ежедневно.Кроме того, приложение не находилось под большой нагрузкой в любое время.