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