Назад | Перейти на главную страницу

Почему одна и та же служба Java использует до 4 раз больше ОЗУ при работе 1 ядра и 2 ядер

У меня есть образ виртуальной машины Ubuntu 18.04, который запускает серверный процесс на основе Java 8. При работе на одноядерном EC2 t2.small экземпляр (2 ГБ ОЗУ) он начинается с RSS 432M. Запуск того же образа сервера как t3.small (двухъядерный, тот же 2 ГБ RAM), сервис запускает до 876M RSS. В Java 10 разница еще более значительна: иногда она начинается с 1586M RSS. И производительность сильно падает.

Ни в коем случае не используется своп.

Точно такой же образ сервера, очень разные результаты. Единственная значимая переменная - это количество ядер.

ОДНАКО после бега jmap Чтобы увидеть, как используется куча, я заметил, что RSS упал наполовину, примерно там, где я ожидал, что он будет на t2. И дампы кучи не показали реальной разницы в фактическом распределении между t2 или t3, Java 8 или Java 10.

Итак, мне интересно: это JVM или ОС, которые действуют по-другому? Я знаю, что могу играть с MaxHeapFreeRatio чтобы JVM быстрее высвобождала память, но это JVM, реагирующая на состояние памяти, или ОС?

Размер кучи по умолчанию действительно зависит от количества процессоров и исходит от JVM. Из Java 8 документация: машина серверного класса - это машина с как минимум 2 процессорами и как минимум 2 ГБ физической памяти.

t2.small - это одноядерный экземпляр, поэтому java по умолчанию использует настройки клиентской JVM и начинается с меньшего размера кучи.

t3.small попадает в настройки JVM сервера, JVM запускается с большим размером кучи.

Максимальный размер кучи фактически не используется JVM, если ваша программа не создаст достаточно объектов, чтобы этого потребовать. Он предназначен только для возможного использования в будущем.

Доступна дополнительная информация о Java 8 Вот, и я считаю, что Java 10 имеет только более новые / более высокие значения по умолчанию, но логика та же.