У меня есть образ виртуальной машины Ubuntu 18.04, который запускает серверный процесс на основе Java 8. При работе на одноядерном экземпляре EC2 t2.small
(2 ГБ ОЗУ) он запускается с RSS 432M. Запустив тот же образ сервера, что и t3.small
(двухъядерный, те же 2 ГБ ОЗУ), сервис при запуске запускает до 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 имеет только более новые / более высокие значения по умолчанию, но логика такая же.