Ограничение памяти 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.