JIT-компилятор Java вызывает OutOfMemoryError

Приложение, которое мы недавно начали время от времени сбой, с сообщением о «java.lang.OutOfMemoryError: запрошено 8589934608 байт для Chunk :: new. Недостаточно места подкачки?».

Я посмотрел вокруг в сети, и везде предложения ограничены

вернуться к предыдущей версии Javaвозиться с настройками памятииспользовать клиент вместо режима сервера

Возвращение к предыдущей версии подразумевает, что в новой Java есть ошибка, но я не видел никаких признаков этого. Память не проблема вообще; на сервере доступно 32 ГБ, а для Xmx установлено значение 20, а для Xms - 10. Я не вижу, чтобы JVM исчерпала оставшиеся 12 ГБ (за вычетом суммы, выделенной нескольким другим процессам на машине). И мы застряли в режиме сервера из-за характера приложения и среды.

Когда я смотрю на использование памяти и ЦП для приложения, я вижу постоянное использование памяти в течение всего дня, но затем, как раз перед тем, как оно умирает, загрузка ЦП возрастает до 100%, а использование памяти изменяется от Х до Х + 2 ГБ, до X + 4 ГБ, (иногда) до X + 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 недели, хотя приложение запускается каждый день и перезапускается ежедневно. Кроме того, приложение не находилось под большой нагрузкой ни разу.

Ответы на вопрос(0)

Ваш ответ на вопрос