容器中 Java 应用程序的内存和 CPU 如何分配?看这一篇就够了!

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 随着2018年的结束,我们将回顾排名前五的最受读者欢迎的文章。今天分享的第一篇文章,将帮助那些在容器中运行 Java 虚拟机(JVM)时遇到内存和 CPU 大小调整/使用困难的人,本文将解释如何在 Docker Desktop(Mac或Windows)和 Docker Enterprise 环境中改进 Docker 容器与 Java 10的集成。

screenshot

出品丨Docker公司(ID:docker-cn)
编译丨小东
每周一、三、五,与您不见不散!


随着2018年的结束,我们将回顾排名前五的最受读者欢迎的文章。今天分享的第一篇文章,将帮助那些在容器中运行 Java 虚拟机(JVM)时遇到内存和 CPU 大小调整/使用困难的人,本文将解释如何在 Docker Desktop(Mac或Windows)和 Docker Enterprise 环境中改进 Docker 容器与 Java 10的集成。


许多应用程序都以容器的形式运行在 Java 虚拟机(JVM)中,其中包括 Apache Spark 和 Kafka 等数据服务以及旧的企业级应用程序。直到最近,在容器中运行 Java 虚拟机会出现内存和cpu大小以及使用方面的问题,从而导致性能损失。这是因为 Java 没有识别到它是在容器中运行的。随着 Java 10的发布,Java 虚拟机现在可以识别容器控制组(cgroups)设置的约束。内存和 cpu 约束都可以用于直接在容器中管理 Java 应用程序,包括:

  • 遵守容器中设置的内存限制;
  • 在容器中设置可用的 cpu;
  • 在容器中设置 cpu 约束;

Docker Desktop(Mac 或 Windows)和 Docker Enterprise 环境都实现了 Java 10的改进。


容器内存限制

在 Java 9之前,Java 虚拟机无法识别容器使用标记设置的内存或CPU限制。在Java 10中,内存限制将自动进行识别并强制执行。

Java 将服务器类机器定义为具有2个 CPU 和 2GB 内存,默认堆大小为物理内存的1/4。 例如,Docker Enterprise Edition 安装有2GB内存和4个CPU。比较运行 Java 8和 Java 10之间容器的区别。首先,Java 8:

docker container run -it -m512 --entrypoint bash openjdk:latest
$ docker-java-home/bin/java -XX:+PrintFlagsFinal -version | grep MaxHeapSize
   uintx MaxHeapSize := 524288000 {product}
openjdk version "1.8.0_162"

最大堆大小为 512M 或 Docker EE 安装设置的 2GB 的1/4,而不是容器上设置的限制为512M。 相比之下,在 Java 10上运行相同的命令表明容器中设置的内存限制非常接近预期的128M:

docker container run -it -m512M --entrypoint bash openjdk:10-jdk
$ docker-java-home/bin/java -XX:+PrintFlagsFinal -version | grep MaxHeapSize
  size_t MaxHeapSize = 134217728 {product} {ergonomic}
openjdk version "10" 2018-03-20

设置可用的CPU

默认情况下,每个容器对主机 CPU 周期的访问权限是不受限制的。可以设置各种约束来限制给定容器对主机 CPU 周期的访问。Java 10可以识别出这些限制:

docker container run -it --cpus 2 openjdk:10-jdk
jshell> Runtime.getRuntime().availableProcessors()
$1 ==> 2

分配给 Docker EE 的所有 CPU 获得相同比例的 CPU 周期。可以通过相对于所有其他正在运行的容器的权重更改容器的 CPU 份额权重来修改该比例。该比例仅适用于 CPU 密集型进程运行时。当一个容器中的任务空闲时,其他容器可以使用剩余的 CPU 时间。 实际的 CPU 时间量将根据系统上运行的容器数量而有所不同。这些可以在 Java 10中进行设置:

docker container run -it --cpu-shares 2048 openjdk:10-jdk
jshell> Runtime.getRuntime().availableProcessors()
$1 ==> 2

“cpuset” 约束设置了哪些 cpu 允许在 Java 10中执行。

docker run -it --cpuset-cpus="1,2,3" openjdk:10-jdk
jshell> Runtime.getRuntime().availableProcessors()
$1 ==> 3

分配内存和 CPU

使用 Java 10,容器设置可用于估计部署应用程序所需的内存和 CPU 分配。假设已经确定了容器中运行的每个进程的内存堆和 CPU 需求,并设置了 JAVA_OPTS。例如,如果您的应用程序分布在10个节点上,五个节点需要512Mb内存,每个节点占用 1024 CPU,另外五个节点需要256Mb内存,每个节点占用 512 CPU共享。请注意,1个CPU份额比例由 1024 表示。

对于内存,应用程序至少需要分配 5Gb 内存。

  • 512Mb x 5 = 2.56 Gb
  • 256Mb x 5 = 1.28 Gb

对于 CPU,应用程序需要分配8个CPU才能高效运行。

  • 1024 x 5 = 5 CPUs
  • 512 x 5 = 3 CPUs

最佳实践建议:分析应用程序以确定 Java 虚拟机中运行的每个进程的内存和 CPU 分配。无论如何,Java 10在调整容器大小时消除了猜测,预防了 Java 应用程序中的内存不足错误以及保障了分配足够的 CPU 来处理工作负载。

相关文章
|
3月前
|
关系型数据库 MySQL API
|
2月前
|
监控 Docker 容器
在Docker容器中运行打包好的应用程序
在Docker容器中运行打包好的应用程序
|
2月前
|
Java 对象存储 开发者
如何找出Java进程占用CPU高的元凶
本文记录了一次Java进程CPU占用率过高的问题和排查思路。
|
2月前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
227 7
|
2月前
|
开发框架 .NET PHP
网站应用项目如何选择阿里云服务器实例规格+内存+CPU+带宽+操作系统等配置
对于使用阿里云服务器的搭建网站的用户来说,面对众多可选的实例规格和配置选项,我们应该如何做出最佳选择,以最大化业务效益并控制成本,成为大家比较关注的问题,如果实例、内存、CPU、带宽等配置选择不合适,可能会影响到自己业务在云服务器上的计算性能及后期运营状况,本文将详细解析企业在搭建网站应用项目时选购阿里云服务器应考虑的一些因素,以供参考。
|
3月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
265 13
|
2月前
|
存储 缓存 前端开发
JavaEE初阶——初识EE(Java诞生背景,CPU详解)
带你从零入门JAVAEE初阶,Java的发展历程认识什么是cpu,cpu的工作原理,cpu是如何进行计算的,cpu的架构,指令集,cpu的核心,如何提升cpu的算力,cpu的指令,,cup的缓存,cpu的流水线
|
3月前
|
SQL 安全 Java
安全问题已经成为软件开发中不可忽视的重要议题。对于使用Java语言开发的应用程序来说,安全性更是至关重要
在当今网络环境下,Java应用的安全性至关重要。本文深入探讨了Java安全编程的最佳实践,包括代码审查、输入验证、输出编码、访问控制和加密技术等,帮助开发者构建安全可靠的应用。通过掌握相关技术和工具,开发者可以有效防范安全威胁,确保应用的安全性。
71 4
|
3月前
|
弹性计算 Kubernetes Perl
k8s 设置pod 的cpu 和内存
在 Kubernetes (k8s) 中,设置 Pod 的 CPU 和内存资源限制和请求是非常重要的,因为这有助于确保集群资源的合理分配和有效利用。你可以通过定义 Pod 的 `resources` 字段来设置这些限制。 以下是一个示例 YAML 文件,展示了如何为一个 Pod 设置 CPU 和内存资源请求(requests)和限制(limits): ```yaml apiVersion: v1 kind: Pod metadata: name: example-pod spec: containers: - name: example-container image:
490 1
|
3月前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
1265 2