Ограничение памяти Java-приложения и использования процессора

Скажите: "запустите myApp.jar с процессором =800 и памятью =1024"

Я занимался программированием на Java в течение многих лет, и мне стыдно задавать этот вопрос. Я даже не знаю, возможно ли это или нет. И если да, то как?

То, что я просто хочу знать, это то, можно ли установить максимальное использование памяти java-программой и процессор. Я вдруг подумал об этом, потому что недавно начал разрабатывать мобильные приложения. Я хочу знать, как приложение будет вести себя на устройстве, которое имеет очень ограниченную память и процессор.

Я видел физические движки с демонстрационными приложениями, которые запускаются в браузере или могут работать на моем ПК. Что делать, если я запускаю их на мобильном устройстве? Будет ли производительность такой же? Вместо того, чтобы разрабатывать образец мобильного приложения для проверки производительности библиотеки, я бы предпочел запустить его с определенным процессором и памятью, используя сначала мой ПК.

Кстати, я попробовал поискать в Google... все, что я нашел, это мониторинг и настройка производительности. Я могу использовать неправильные ключевые слова.

9 ответов

Решение

Вы можете ограничить использование памяти с помощью опции -Xmx, а также ограничить использование ЦП, установив приоритет процесса и / или привязку ЦП.

JVM не контролирует использование ЦП и приоритет.

JVM имеет контроль над использованием памяти max/min.

Есть обходной путь. Можно запустить каждую JVM в отдельном контейнере Docker. И контролировать распределение ресурсов (память, процессор, сеть, ввод-вывод) для каждого контейнера. Это и есть добавленная стоимость контейнеров Docker.

Linux:

taskset -a -c 0,1,2,3 <program>

Запускайте программу и ее дочерние потоки только на ядрах 0, 1, 2 и 3.

Docker предлагает опции управления ресурсами для ограничения доступа к процессору для запуска контейнеров Docker. Посмотрите на опции планировщика CFS, доступные с docker run Ограничить ресурсы контейнера в документации Docker, такие как:

  • --cpus=<value> - Укажите, сколько доступных ресурсов ЦП может использовать контейнер. Например, если на хост-машине установлено два ЦП, и вы установили --cpus="1.5"Контейнеру гарантировано максимум полтора процессора. Это эквивалент настройки --cpu-period="100000" а также --cpu-quota="150000", Доступно в Docker 1.13 и выше.
  • --cpuset-cpus - Ограничить конкретные процессоры или ядра, которые контейнер может использовать. Разделенный запятыми список или разделенный дефисом ЦП, которые может использовать контейнер, если у вас более одного ЦП. Первый ЦПУ имеет номер 0. Допустимое значение может быть 0-3 (использовать первый, второй, третий и четвертый ЦП) или 1,3 (использовать второй и четвертый процессор).

Эти опции также доступны через docker-compose, при развертывании роя / стека Docker, как упоминалось в справочнике Compose file version 3 под resources:

version: '3'
services:
  redis:
    image: redis:alpine
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 50M
        reservations:
          cpus: '0.25'
          memory: 20M```

Обратите внимание: что устаревшие опции ресурсов в docker compose v2 теперь ограничены стеками при переходе на v3.

Для процессора вы можете попробовать мою новую библиотеку:).

https://github.com/dyorgio/cpu-watcher

Пример использования:

// Limit process by PID to 25% of host cpu usage
CpuWatcher cpuWatcher = new CpuWatcher(pid, 25f);
cpuWatcher.start();

Пожалуйста, будьте осторожны с памятью и процессором при запуске jvm 8 или более ранней версии. Есть несколько очень хороших статей об этом. Проверьте это:

https://developers.redhat.com/blog/2017/03/14/java-inside-docker/

https://jaxenter.com/nobody-puts-java-container-139373.html

Сказав это, контейнеризация - это правильный путь для микросервисной архитектуры независимо от стека, и jvm не является исключением из этого. Однако важно знать о предостережениях.

https://github.com/haosdent/jcgroup jcgroup - ваш лучший выбор. Вы можете использовать эту библиотеку для ограничения общих ресурсов процессора, скорости дискового ввода-вывода, пропускной способности сети и т. Д.

Для систем с ограниченными ресурсами я однажды нашел следующие параметры командной строки java полезными для моего конкретного случая использования (проверено с OpenJDK 17). Он ограничивает память кучи (начальный:-Xms, максимум:-Xmx), абсолютный максимум ОЗУ, а также устанавливает использование только последовательного сборщика мусора, чтобы вызывать меньше спонтанных всплесков загрузки ЦП:

java -Xmx512m -Xms128m -XX:MaxRAM=1536m -XX:+UseSerialGC

Конечно, вы должны выяснить, будет ли ваше приложение работать с этими настройками.

В этом случае это может помочь запустить приложение на мобильном эмуляторе (например, Android).

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

Эмулятор Android / Nokia является бесплатным и доступен для загрузки в разделах для разработчиков на сайтах Nokia/Google.

Другие вопросы по тегам