JIT-компилятор Java вызывает OutOfMemoryError - PullRequest
9 голосов
/ 11 августа 2010

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

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

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

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

Когда я смотрю на использование памяти и ЦП для приложения, я вижу постоянное использование памяти в течение всего дня, но затем внезапнопрямо перед смертью загрузка ЦП возрастает до 100%, а использование памяти изменяется от Х до Х + 2 ГБ, до Х + 4 ГБ, до (иногда) Х + 8 ГБ до смерти JVM.Может показаться, что в JIT-компиляции происходит цикл повторного изменения размера массива.

Я уже видел, что ошибка возникает с запросом 8GB выше, а также с запросами 16GB.Когда это происходит, метод компиляции всегда один и тот же.Это простой метод, который имеет не вложенные циклы, не имеет рекурсии и использует методы для объектов, которые возвращают статические поля-члены или поля-члены экземпляра напрямую без малейших вычислений.

Итак, у меня есть 2 вопроса:

  1. Есть ли у кого-нибудь какие-либо предложения?
  2. Могу ли я проверить, есть ли проблема при компиляции этого конкретного метода в тестовой среде, без запуска всего приложения и непосредственного вызова компилятора JIT?Или я должен запустить приложение и сказать ему, чтобы он компилировал методы после гораздо меньшего числа вызовов (например, 2), чтобы заставить его компилировать метод почти мгновенно, а не в случайную точку дня?

@ StephenC

JVM - 1.6.0_20 (ранее 1.6.0_0), работающая на Solaris.Я знаю, что компиляция вызывает проблему по нескольким причинам.

  1. ps в секундах, предшествующих этому, показывает, что поток Java с идентификатором, соответствующим потоку компилятора (из jstack)занимает 100% процессорного времени
  2. jstack показывает, что проблема в JavaThread "CompilerThread1" daemon [_thread_in_native, id=34, ...]

Метод, упомянутый в jstack, всегда один и тот же итот, который мы написали.Если вы посмотрите пример вывода jstack, вы поймете, что я имею в виду, но по понятным причинам я не могу предоставить примеры кода или имена файлов.Я скажу, что это очень простой метод.Essentiall несколько пустых проверок, 2 для циклов, которые делают проверки на равенство и, возможно, присваивают значения, и некоторые простые вызовы методов после.Всего может быть 40 строк кода.

Эта проблема возникала 2 раза за 2 недели, хотя приложение запускается каждый день и перезапускается ежедневно.Кроме того, приложение не находилось под большой нагрузкой в ​​любое время.

Ответы [ 3 ]

5 голосов
/ 14 августа 2010

Вы можете исключить конкретный метод из JIT-файла, создав файл с именем .hotspot_compiler и поместив его в «рабочий каталог» вашего приложения. Просто добавьте запись в файл в следующем формате:

exclude com/amir/SomeClass someMethod

И вывод консоли от компилятора будет выглядеть так:

### Excluding compile:  com.amir.SomeClasst::someMethod

Для получения дополнительной информации прочитайте это . Если вы не уверены, что «рабочий каталог» вашего приложения, используйте

-XX:CompileCommandFile=/my/excludefile/location/.hotspot_compiler

в вашем скрипте запуска Java или командной строке.

В качестве альтернативы, если вы не уверены, что это ошибка компилятора JIT, и хотите посмотреть, сможете ли вы воспроизвести проблему без использования JIT, запустите ваш Java-процесс с помощью -Xint.

1 голос
/ 11 августа 2010

Вот еще одна запись на форуме оракулов .Похоже спорадическая катастрофа.Есть один ответ, где один решил проблему путем перенастройки коэффициента выживаемости gc.

1 голос
/ 11 августа 2010

Хорошо, я сделал быстрый поиск и нашел ветку на форумах Sun java , в которой обсуждается .Надеюсь, это поможет.

...