Распознавание того, требует ли мое Java-приложение больше оперативной памяти, чем предлагает машина - PullRequest
0 голосов
/ 11 октября 2018

Я работаю с большим Java-приложением.Его процесс может потребовать большой объем памяти из-за обработки большой геометрии, в зависимости от набора данных, используемая память достигает пика около 12 ГБ во время выполнения.

Приложение использует javacpp для обработки данных на стороне C ++.

В наших спецификациях клиента указано, что на компьютерах, на которых установлено приложение, установлено не менее 16 ГБ ОЗУ, однако мы часто обнаруживаем, что клиенты игнорируют эти спецификации.и сталкиваются с различными ошибками, среди которых EXCEPTION_ACCESS_VIOLATION.Мы начинаем сталкиваться с этой проблемой, как только приложение начинает широко использовать файл подкачки, по всей вероятности, буфер не выделяется во времени или не в указанном размере (сторона C ++), так что приложение предполагает доступность памяти, которая не является (Сторона Java).

Мы находимся в процессе отладки этого поведения, однако различные источники (такие как этот: высокая загрузка подкачки ) указывают, что такое поведение несколько ожидается, когда приложение Javaв основном начинает использовать swap-space.И опять же, это обычно начинает происходить, когда используются машины с 4 ГБ ОЗУ или 8 ГБ ОЗУ, и почти никогда не происходит на машинах, удовлетворяющих требованиям 16 ГБ ОЗУ.

В настоящее время согласовано решение, которое просто предупреждает пользователя, если его компьютернедостаточно для использования оперативной памяти приложения.

Так много для контекста.Проблема, с которой я сталкиваюсь, заключается в том, чтобы выяснить, достаточно ли оперативной памяти для того, что пользователь собирается делать, и / или если приложение в основном использует пространство подкачки.

Есть ли какие-либо известныетактика, чтобы узнать эту информацию?

Что я пробовал до сих пор:

Я кратко проверил Runtime.getRuntime().freeMemory(), а также Runtime.getRuntime().maxMemory() и Runtime.getRuntime().totalMemory() в соответствии с тем, что было описано здесь:

Java получает доступную память

Насколько я вижу из полученных значений, это всего лишь куча памяти.

Поэтому, кроме того, я использую Pointer#availablePhysicalBytes, предоставленный javacpp .См .:

http://bytedeco.org/javacpp/apidocs/org/bytedeco/javacpp/Pointer.html

Таким образом может быть получено считывание фактической свободной физической памяти, доступной для системы.Однако, похоже, что подкачка начинается задолго до того, как будут достигнуты пределы памяти, поэтому, если я собираюсь проверить с помощью Pointer#availablePhysicalBytes, мне нужно выбрать разумный порог.Другой источник из StackOverflow утверждает, что обмен начинается примерно на 75% занятой физической ОЗУ, утверждение, которое я не нашел в других местах до сих пор.

Так что мои конкретные вопросы таковы:

1) Если мы решимпроверьте наличие свободной оперативной памяти и используйте пороговое значение, чтобы решить, может ли JVM столкнуться с риском стать нестабильным - как рассчитывать такой порог?Можно предположить, что я могу получить как общую, так и свободную оперативную память для расчета порога.

2) Есть ли способ проверить, использует ли приложение Java файл подкачки (есть ли способ проверить это?)вообще)?

3) Можно ли считать любой из этих подходов разумным?Если нет, то существует ли более эффективная практика для определения того, не удовлетворяет ли машина пользователя текущим потребностям приложения Java во время выполнения по отношению к физической памяти?

...