У меня есть следующая ситуация: есть несколько машин, образующих кластер. Клиенты могут загружать наборы данных, и нам нужно выбрать node, на котором будет загружен набор данных, и отказаться от загрузки/исключения ошибки OOM, если нет машины, которая могла бы соответствовать набору данных.
Что мы делаем сейчас: теперь entry count
в наборе данных и оцениваем memory to be used
как entry count * empirical factor
(определяется вручную). Затем проверьте, меньше ли это свободной памяти (полученной Runtime.freeMemory()
), и если да, загрузите ее (в противном случае повторите процесс на других узлах/сообщите, что свободной емкости нет).
Проблемы с этим подходом:
-
empirical factor
необходимо повторно просмотреть и обновить вручную -
freeMemory
иногда может занижать отчет из-за некоторого не очищенного мусора (чего можно избежать, выполнивSystem.gc
перед каждым таким вызовом, однако это замедлит работу сервера, а также потенциально может привести к преждевременному продвижению) - альтернативой было бы "просто попытаться загрузить набор данных" (и вернуться, если OOM будет выброшен), однако после того, как OOM будет сброшен, вы потенциально повредили другие потоки, запущенные в одной JVM, и нет изящного способа оправившись от него.
Есть ли лучшие решения этой проблемы?