HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Теги: docker, java, программирование на java, разработка на java, java 10, контейнер</p>
1 <p>Теги: docker, java, программирование на java, разработка на java, java 10, контейнер</p>
2 <p>Сейчас Java всё чаще используется в контейнерах, обычно в<strong>Docker</strong>. Формально в Docker можно положить любую версию Java, и это даже как-то будет работать. Однако когда вышла<strong>Java 8</strong>, про работу в Docker ещё никто и не думал. В результате<strong>Java-приложение</strong>хоть и работает,<strong>но не понимает</strong>, что находится в ограниченном окружении.<strong>Не видит ограничение Docker-а</strong>на использование процессора и памяти.</p>
2 <p>Сейчас Java всё чаще используется в контейнерах, обычно в<strong>Docker</strong>. Формально в Docker можно положить любую версию Java, и это даже как-то будет работать. Однако когда вышла<strong>Java 8</strong>, про работу в Docker ещё никто и не думал. В результате<strong>Java-приложение</strong>хоть и работает,<strong>но не понимает</strong>, что находится в ограниченном окружении.<strong>Не видит ограничение Docker-а</strong>на использование процессора и памяти.</p>
3 <p>Это приводит к весьма неприятным последствиям. Например,<strong>приложение не учитывает ограничение на процессоры</strong>и может создавать пулы с большим количеством потоков или не видит ограничение по памяти и неожиданно закрывается Docker-ом при превышении лимита.</p>
3 <p>Это приводит к весьма неприятным последствиям. Например,<strong>приложение не учитывает ограничение на процессоры</strong>и может создавать пулы с большим количеством потоков или не видит ограничение по памяти и неожиданно закрывается Docker-ом при превышении лимита.</p>
4 <p>Работа в контейнере начала улучшаться, начиная c<strong>Java 9</strong>(есть и обратные порты в Java 8), в релизе<strong>Java 10</strong>был добавлен новый параметр UseContainerSupport. Этот параметр сообщает<strong>Java-приложению</strong>, что оно запущено в контейнере и необходимо учитывать наложенные ограничения, а не использовать все ресурсы операционной системы без ограничений.</p>
4 <p>Работа в контейнере начала улучшаться, начиная c<strong>Java 9</strong>(есть и обратные порты в Java 8), в релизе<strong>Java 10</strong>был добавлен новый параметр UseContainerSupport. Этот параметр сообщает<strong>Java-приложению</strong>, что оно запущено в контейнере и необходимо учитывать наложенные ограничения, а не использовать все ресурсы операционной системы без ограничений.</p>
5 <p>Давайте посмотрим, как это работает. По умолчанию UseContainerSupport включён, т. е. приложение видит ограничения контейнера. Положим в контейнер простое приложение, которое выводит количество доступных процессоров:</p>
5 <p>Давайте посмотрим, как это работает. По умолчанию UseContainerSupport включён, т. е. приложение видит ограничения контейнера. Положим в контейнер простое приложение, которое выводит количество доступных процессоров:</p>
6 Runtime.getRuntime().availableProcessors().<p>Соберём образ и запустим контейнер такой командой:</p>
6 Runtime.getRuntime().availableProcessors().<p>Соберём образ и запустим контейнер такой командой:</p>
7 docker run --memory=100m --cpus 2 java-docker<p>Вводим ограничение для контейнера: память 100 Мб и 2 процессора. В контейнере запускается такая команда:</p>
7 docker run --memory=100m --cpus 2 java-docker<p>Вводим ограничение для контейнера: память 100 Мб и 2 процессора. В контейнере запускается такая команда:</p>
8 CMD java -XX:+PrintFlagsFinal -version | grep MaxHeapSize<p>Получаем результат:</p>
8 CMD java -XX:+PrintFlagsFinal -version | grep MaxHeapSize<p>Получаем результат:</p>
9 size_t MaxHeapSize = 52428800<p>Это примерно 52 Мб, т. е. примерно половина лимита контейнера.Теперь посмотрим на доступные процессоры:</p>
9 size_t MaxHeapSize = 52428800<p>Это примерно 52 Мб, т. е. примерно половина лимита контейнера.Теперь посмотрим на доступные процессоры:</p>
10 CMDjava -jartestJavaAppl.jar<p>Возвращает:</p>
10 CMDjava -jartestJavaAppl.jar<p>Возвращает:</p>
11 Runtime.getRuntime().availableProcessors(): 2<p>Видим, что Java-приложение учитывает в своей работе лимиты, заданные контейнером. Давайте повторим эксперимент, но на этот раз отключим режим UseContainerSupport - это<strong>фактически вернёт нас во времена Java 8</strong>. Ограничения контейнера те же. Смотрим память:</p>
11 Runtime.getRuntime().availableProcessors(): 2<p>Видим, что Java-приложение учитывает в своей работе лимиты, заданные контейнером. Давайте повторим эксперимент, но на этот раз отключим режим UseContainerSupport - это<strong>фактически вернёт нас во времена Java 8</strong>. Ограничения контейнера те же. Смотрим память:</p>
12 CMD java -XX:-UseContainerSupport -XX:+PrintFlagsFinal -version | grep MaxHeapSize<p>Получаем:</p>
12 CMD java -XX:-UseContainerSupport -XX:+PrintFlagsFinal -version | grep MaxHeapSize<p>Получаем:</p>
13 size_tMaxHeapSize = 8415870976<p>Java не видит ограничение в 100 Мб и пытается использовать память "на всю котлету". А теперь смотрим, что происходит с процессором:</p>
13 size_tMaxHeapSize = 8415870976<p>Java не видит ограничение в 100 Мб и пытается использовать память "на всю котлету". А теперь смотрим, что происходит с процессором:</p>
14 CMD java -XX:-UseContainerSupport -jar testJavaAppl.jar<p>Получаем:</p>
14 CMD java -XX:-UseContainerSupport -jar testJavaAppl.jar<p>Получаем:</p>
15 Runtime.getRuntime().availableProcessors(): 12<p>И по процессорам Java пытается использовать все системные ресурсы, игнорируя ограничения Docker-а. Очевидно, что для корректной работы Java-приложения в Docker-е желательно использовать версию<strong>Java 10</strong>или новее.</p>
15 Runtime.getRuntime().availableProcessors(): 12<p>И по процессорам Java пытается использовать все системные ресурсы, игнорируя ограничения Docker-а. Очевидно, что для корректной работы Java-приложения в Docker-е желательно использовать версию<strong>Java 10</strong>или новее.</p>
16 <p>В следующей заметке затронем другие аспекты работы<strong>Java-приложения в контейнере</strong>. А более подробно посмотрим на это дело на открытом вебинаре "<a>Java и Docker</a>".</p>
16 <p>В следующей заметке затронем другие аспекты работы<strong>Java-приложения в контейнере</strong>. А более подробно посмотрим на это дело на открытом вебинаре "<a>Java и Docker</a>".</p>
17  
17