首页 > 系统相关 >让JVM适应Docker限制:动态调整内存

让JVM适应Docker限制:动态调整内存

时间:2023-12-14 17:31:45浏览次数:28  
标签:容器 限制 JVM XX 内存 cgroup Docker


背景

在现代应用开发中,容器化技术(如Docker)已经成为主流。但是,Java应用在容器中运行时面临着挑战:传统的JVM内存设置需要在启动时指定静态的堆内存大小,这种设置方法难以适应动态变化的容器环境。由于容器环境受到cgroup限制,传统的静态内存配置可能导致资源不足或浪费。因此,让JVM能够感知并适应Docker的内存限制变得至关重要。

cgroup的原理和限制

cgroup(Control Group)是Linux内核提供的机制,用于限制和分配系统资源,如CPU、内存、网络带宽等。在容器环境中,Docker使用cgroup来限制容器可以使用的资源。通过为进程组分配资源并监控资源使用情况,cgroup确保容器不会超出其分配的资源,其中包括内存限制,以确保容器不会消耗超出其分配的资源。

JVM动态适应cgroup限制的重要性

  • 资源管理:cgroup限制确保容器不会占用超出其分配的资源,但传统的JVM内存配置无法动态适应这些限制。
  • 性能优化:让JVM能够感知cgroup限制并动态调整内存,有助于优化性能并充分利用可用资源。
  • 避免浪费:静态内存配置可能导致资源浪费或内存不足的问题,而动态调整能够更好地适应变化的负载。

JDK版本和对应的JVM参数

  • <8u131
  • -Xmx3072m:最大堆大小为3GB。
  • -Xms2048m:初始堆大小为2GB。
  • -XX:MaxMetaspaceSize=256m:元空间最大大小为256MB。
  • 8u131-191
  • -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap:启用实验性的cgroup内存限制感知。
  • -XX:MaxRAMFraction=1:设置为1,允许JVM使用cgroup内存限制的100%。
  • >8u191
  • -XX:UseContainerSupport:默认启用,支持容器。
  • -XX:ActiveProcessorCount:设置CPU限制。
  • -XX:MaxRAMPercentage=90.0:最大堆内存占容器可用内存的百分比。
  • -XX:InitialRAMPercentage=50.0:初始堆内存占容器可用内存的百分比。
  • -XX:MinRAMPercentage=50.0:最小堆内存占容器可用内存的百分比。

案例

场景

考虑一个大型Web应用,使用Java编写并在Docker容器中部署。在高负载时,应用需要更多的内存以满足需求,但在低负载时又不需要使用那么多内存。传统的静态内存配置会导致资源浪费或内存不足的问题。

解决方案

随着JDK版本的演变,Java提供了更多动态适应容器环境的JVM参数。在较新的JDK版本中,使用-XX:MaxRAMPercentage-XX:InitialRAMPercentage等参数,JVM能够以百分比的形式动态调整堆内存大小,充分利用容器可用内存。这意味着在高负载时,JVM可以自动增加堆内存,而在低负载时则会相应地减少堆内存,更好地适应资源需求。

实验

docker run -m 100MB -it openjdk:8u201 sh
JAVA_OPTS="-XX:MaxRAMPercentage=80.0 -XX:MinRAMPercentage=80.0 -XX:MinRAMPercentage=80.0"
java $JAVA_OPTS -XshowSettings:vm -version

结果

VM settings:
    Max. Heap Size (Estimated): 78.5M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

JVM使用可用内存/MaxRAMFraction作为最大堆。使用-XX:MaxRAMFraction=80,我们将几乎所有可用内存用作最大堆。从上面的结果可以看出来内存分配已经可以达到了78.5M。

结论

Java应用在容器化环境中动态感知和适应Docker的内存限制至关重要。通过使用不同JDK版本提供的动态适应性参数,如-XX:MaxRAMPercentage和-XX:InitialRAMPercentage,JVM能够更灵活地调整堆内存大小,以适应不同负载下的资源需求。这种动态调整的能力有助于提高资源利用率、优化性能,并避免了因为静态内存配置而可能导致的资源浪费或内存不足问题。这进一步推动了Java应用在容器化环境中的可靠性和灵活性。

标签:容器,限制,JVM,XX,内存,cgroup,Docker
From: https://blog.51cto.com/jiemei/8822370

相关文章

  • docker-挂载数据卷实现不重启Nginx容器展示不同的网页内容
    dockerpullnignxdockervolumecreatetest_volumesdockerrun-d-p80:80-hnginx--namenginx--mounttype=bind,source=/var/lib/docker/volumes/test_volumes,destination=/var/nginx/htmlnginx#-hnginx是必须的,不然就要去更改容器里面的Nginx.conf配置项容器......
  • window10下ubuntu系统安装docker服务启动不起来问题排查解决。
    https://blog.csdn.net/VeryLost/article/details/128611800 因为最新版的ubuntu系统使用了iptables-nft,而WSL2不支持导致的。需要使用如下命令修改信息:root@username:/#update-alternatives--configiptablesThereare2choicesforthealternativeiptables(providing......
  • docker overlay2引发磁盘爆满
    前因:最近服务器磁盘占比超过90%,log已经清理,发现/data/docker/overlay2目录占用70%了 1.尝试清理docker未用镜像:dockerimageprune删除所有未使用的Docker资源,包括容器、镜像、卷和网络等(慎用,小心删除有用容器)dockerps-a|grepExitdockersystemprune 2.查......
  • SpringBoot中项目启动及定时任务缓存数据库常用数据至内存变量并转换后高频调用
    场景定时任务中需要获取数据库中数据进行数据转换成需要的格式并进行后续的业务处理。数据库中的数据更新频率不高。可将数据库中数据在项目启动后读取一遍数据,然后再通过定时任务定时查询数据库更新数据。实现数据库缓存的方式有多种,比如以下:SpringBoot中通过自定义缓存注解......
  • 利用Docker和CLion在Mac优雅地开发和调试Linux C++程序
    利用Docker和CLion在Mac优雅地开发和调试LinuxC++程序starrymarin计算机主业,间断性健身爱好者,摩托、金融入门​关注他 27人赞同了该文章最近在做一些新的东西,所以学习了一些新的东西,也对旧知识加强了很多,所以终于有东西可以记录一下了。今天先更......
  • centos 7 安装Docker 和 JDK1.8
    centos7.安Docker1、检查是否已经安装docker.   dockerversion系统必须为64位:cat/etc/redhat-release 内核版本必须高于3.10:uname-r 使用 root 权限登录Centos。确保yum包更新到最新。如果是新安装的操作系统,这个过程还是需要一些时间的。前提一定是已......
  • docker~构建java应用程序的正确姿势
    我们的构建和打包,都是在docker环境进行的,你可以使用Dockerfile中的多镜像模式,也可以单独执行,我是在jenkinspipeline中用到这个,所以我单独写,这个使我的Dockerfile更加简洁。构建java项目,我们为了保证宿主机的整洁,我们采用docker的方式进行项目的编译和打包$workspace是在docke......
  • Docker安装Kafka安装zookeeper教程(超详细)
    1Docker安装Kafka安装zookeeper教程(超详细)2app-tier:网络名称3-driver:网络类型为bridge41.dockernetworkcreateapp-tier--driverbridge561、安装zookeeper7Kafka依赖zookeeper所以先安装zookeeper8-p:设置映射端口(默认2181)9-d:后台启动101......
  • 软件测试/测试开发|Docker+Jmeter+InfluxDB+Grafana 搭建性能监控平台
    为什么要搭建性能监控平台?1.1需求背景在用Jmeter获取性能测试结果的时候,Jmeter本身带有聚合报告如下图所示:这个报告有几个很明显的缺点:只能自己看,无法实时共享;报告信息的展示比较简陋单一,不直观;1.2需求方案为了解决上述问题,必须要请出了InfluxDB+Grafana......
  • docker和docker-compose生产的容器,不在同一个网段,解决方式
    在实际项目中,使用dockerrunxxXx 和docker-composeup-d不在同一个网段,一个是默认是172.17.x.x, 另一个是172.19.x.x。为解决这个问题需要自定义一个网络,我命名为“my-bridge”首先熟悉几条命令:dockernetworkls或者dockernetworklist查看当前的docker网络的内容、容器的......