У меня есть образ виртуальной машины 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 имеет только более новые / более высокие значения по умолчанию, но логика та же.