java - 您如何使用 Docker 确定 Java 微服务的堆/非堆大小?

标签 java docker microservices amazon-ecs

我们在 AWS ECS 中运行 Java 微服务。因此,对于 Docker,我们使用 -Xmx 指定了一些硬 Java 堆限制。确定我们可以为堆留多少内存以及我们需要多少非堆内存(元空间、堆栈、JIT 缓存等)是一个非常棘手的部分。 目前,我们正在运行压力测试以确定我们何时拥有 Docker OOMKiller。 例如,对于 2GB AWS 任务(docker),我们可以为堆设置 -Xmx1400m 的最大值(使用 -Xmx1450m 我们没有足够的内存用于非堆内容(退出代码 137)) 实际上,Java 10+ 有“-XX:MaxRAMPercentage”,但我们仍然需要知道这个百分比。

如何确定 Java 微服务的堆/非堆大小?或者压力测试是唯一的解决方案?

最佳答案

自 Java 8u131 起,there is an option to set the JVM limits based on container memory limits .所以如果你运行类似的东西:

docker run \
  -m 2g \     # set a container memory limit
  openjdk:8 \
  java \
    -XX:+UnlockExperimentalVMOptions \
    -XX:+UseCGroupMemoryLimitForHeap \
    com.example.Classname

JVM 将设置堆限制,使其符合 2 GB 容器内存限制,运行 -Xmx为你。原则上这应该安排一些事情,这样你就不会达到容器内存限制,而是得到一个 Java OutOfMemoryError。首先。

This blog post关于该主题还有更多示例,还建议 -XX:MaxRamFraction=1允许使用“所有内存”,你用 docker run -m 限制了它选项。

在实践中你可能会设置$JAVA_OPTS在像这样的 Dockerfile 中

FROM openjdk:8
COPY app.jar /
ENV JAVA_OPTS=-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRamFraction=1
CMD ["java", "-jar", "/app.jar"]

然后像这样运行

docker run -d -p ... -m 2g myimage

在 Kubernetes 环境中,pod 资源约束中声明的内存限制起着相同的作用。

正如@KarolDowbecki 在他们的回答中所建议的那样,您确实需要进行一些分析和监控才能真正为此选择正确的数字。在本地运行应用程序并监控 RSS (驻留集大小)统计在pstop应该给你一个合理的基线。

关于java - 您如何使用 Docker 确定 Java 微服务的堆/非堆大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54700816/

相关文章:

docker - 通过 telnet 连接到 docker 容器

java - 如何从任何地方访问安装在 Kubernetes 上的服务?

java - 基于微服务的架构和每个节点的单独缓存

java - 如何为android studio安装ffmpeg?

docker: error during connect: 在 Windows 上的默认守护程序配置中,docker 客户端必须以提升的权限运行才能连接

java - 在简单的 TicTacToe 游戏中切换大小写

java - 如何将 Docker 添加到我的模块化 Web 应用程序

security - 基于用户或组成员身份的微服务架构中的实体级访问限制

java - 真的很大的字典

java - 当我移动 Web 服务时,所有硬编码 URI 会发生什么情况?