Ошибки при задании java heap size

Ошибки при задании java heap size

Совсем недавно столкнулся с проблемой задания размера кучи памяти (Java heap size) при запуске приложения на удаленной машине через SSH. Проблема заключалась в том, что… я элементарно не мог вспомнить какие буквы используются для задания параметров и в каком порядке!

Хоть и говорят, что Google — далеко не панацея, но с этой моей сложностью он помог справиться довольно быстро. На просторах этого поискового монстра нашлось довольно много информации о том, как задавать размер памяти для запускаемого приложения. Но внимание мое привлекла небольшая статейка (даже скорее сборник рецептов) о том, какие ошибки обычно допускаются при задании heap size.

Предлагаю Вашему вниманию перевод этой статьи.

Два параметра, наиболее часто используемых при задании размера кучи виртуальной машины (JVM heap size), — это -Xmx для максимального и -Xms для начального размера соответственно. Ниже приведены типичные ошибки при использовании этих параметров:

  • Пропущенные m, M, g или  G в конце (кстати, они чувствительны к регистру!). Например:
    java -Xmx128 BigApp
    java.lang.OutOfMemoryError: Java heap space

    Правильно было бы написать java -Xmx128m BigApp. Если быть совсем корректным, то -Xmx128 — это тоже правильное задание размера памяти, но для очень-очень маленьких приложений, как, например, HelloWorld. В действительности же, думаю, речь все же идет именно о -Xmx128m.

  • Лишние пробелы или неверное использование знака равенства «=» в параметрах. Например:
    java -Xmx 128m BigApp
    Invalid maximum heap size: -Xmx
    Could not create the Java virtual machine.
    
    java -Xmx=512m HelloWorld
    Invalid maximum heap size: -Xmx=512m
    Could not create the Java virtual machine.

    Правильным вызовом в этом случае будет java -Xmx128m BigApp, без пробела или «=». Параметры «-X» отличаются от «Dkey=value» системных параметров, в которых используется знак равенства.

  • Задание только минимального размера  -Xms, превышающего максимальный размер по умолчанию (64m). Например:
    java -Xms128m BigApp
    Error occurred during initialization of VM
    Incompatible initial and maximum heap sizes specified

    Правильно было бы, например, так: java -Xms128m -Xmx128m BigApp. Задавать одинаковые минимальный и максимальный размеры вполне правильно. В любом случае, не допускайте того, чтобы минимальный размер был больше максимального.

  • Размер запрашиваемой памяти больше физической памяти компьютера. Например:
    java -Xmx2g BigApp
    Error occurred during initialization of VM
    Could not reserve enough space for object heap
    Could not create the Java virtual machine.

    Задайте размер кучи меньше размера физической памяти: java -Xmx1g BigApp.

  • Неправильное использование метрик, например, использование mb там, где стоит использовать m или M:
    java -Xms256mb -Xmx256mb BigApp
    Invalid initial heap size: -Xms256mb
    Could not create the Java virtual machine.

    Очевидно, здесь нужно просто убрать лишнюю «b»: java -Xms256m -Xmx256m BigApp.

  • JVM считает, что Вам нужно меньше памяти, чем запрашивается. Например:
    java -Xmx256g BigApp
    Invalid maximum heap size: -Xmx256g
    The specified size exceeds the maximum representable size.
    Could not create the Java virtual machine.

    Решить эту проблему можно, если снизить значение параметра до разумных пределов: java -Xmx256m BigApp.

  • Значение представлено в виде десятичной дроби. Например:
    java -Xmx0.9g BigApp
    Invalid maximum heap size: -Xmx0.9g
    Could not create the Java virtual machine.

    Правильно будет, например, так: java -Xmx928m BigApp.

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