K8S(18)容器环境下资源限制与jvm内存回收

一、k8s中的java资源限制与可能的问题

与以前单机跑单服务的情况相比,在k8s、docker容器化环境下的宿主机内存、cpu相对更大,所以当运行java类程序的时候,就必然有必要对容器进行内存限制,否则以java默认参数启动,一个程序就可能吃掉你四分之一的内存

但是怎么限制,就是一个值得考虑的问题了。

方案1:通过JVM的Xms和Xmx参数限制

java -Xms2048m -Xmx2048m -jar register.jar

在非容器化时,最常规的方案;在容器化中,也经常使用向容器传递环境变量的方式,通过控制这两个参数来控制服务的内存使用量

在网上通常的jvm调优方案中,也通常会要求把这两个参数设置为相等(可认为属于调优共识),来较小FGC的频率和提高性能

但是在容器化情况下(假设xmx=xms=4G),存在的问题是:

A 内存不释放问题:

  1. java容器运行后,会慢慢的用到设置的内存上限4G
  2. 由于还有其他的开销,一般会达到6G左右,并且不会释放
  3. 你会发现你宿主机或集群的内存,只升高不降低,除非你重启容器

B 参数设置多少的问题:

  1. 由于给它设置的内存,它总会用完,不好确定到底给它多少内存
  2. 给多了不够用,给少了GC频繁
  3. 有些人要说GC调优确定最合适内存,但这个因素不可控

所以这样,宿主机或集群的总内存,必须得大于你设置的所有容器的内存上限总和才保险

方案2:通过容器的requests和limits参数控制

docker容器和k8s都可以通过参数限制分配给容器的内存大小,同样假设分配了4G,问题会是

  1. 容器资源隔离的原因,容器中看到的内存大小=宿主机的内存大小
  2. 容器中的java服务,不知道自己被限制了内存,会按默认的1/4申请内存
  3. 由于对容器进行了内存限制,所以极大概率该容器运行一段时间后会被重启

方案3:容器参数和JVM参数共用

较可行的方案是两边的参数一起使用,只是要注意容器限制的内存要比jvm设置的大(1-2)G,因为前面说了JVM设置的4G,实际可能会用到6G。

但是共用也没有彻底解决第一个方案中的问题,即:

  1. 给java服务到底分配多少内存
  2. 申请的内存不释放,导致宿主机内存总量上限问题
  3. 多个地方设置内存参数,麻烦

二、解决问题三板斧

主要参考的三个博客

参考1:https://www.cnblogs.com/xiaoqi/p/container-jvm.html

参考2:https://www.imooc.com/article/292785?block_id=tuijian_wz

参考3:https://blog.csdn.net/qq_40378034/article/details/110677269

1)采用JDK8-191以上的jdk版本

由于jdk8-191以前的jdk版本,是不能感知到自己是在容器中运行的,所以对容器设置的资源限制,java程序不能感知,因此会按宿主机的总内存来申请资源

2)使用JVM新的资源限制参数且不相等

java -XX:MaxRAMPercentage=90.0 -XX:MinRAMPercentage=60.0 -jar register.jar

[MAX|MIN]RAMPercentage参数,是191版本后新增加的参数,该参数可以感知容器的资源限制,并以此限制为申请的最大最小资源量,即Xms和Xmx

由参考文章3中的结论:Xms和Xmx不相等时,在可能的情况下,GC过程会慢慢释放内存回操作系统,而我们 设置的[MAX|MIN]RAMPercentage这两个参数不等,达到的结果就是Xms和Xmx不相等

# 此命令可以在容器中验证,java服务按此规则申请时,会申请的内存大小
java -XX:+PrintFlagsFinal -XX:MaxRAMPercentage=90.0 -XX:MinRAMPercentage=60.0 -version | grep -Ei "heapsize|rampercentage"

3)配置容器的资源限制参数

在前两条的基础上,最后在配合容器的资源限制功能后,就能做到

  1. 限制容器的内存上限
  2. 容器内的jvm服务,能根据资源限制来申请内存
  3. 由于jvm会释放内存,所以可先设一个较大值,经过长期观察,可以确定该服务的常规内存水平
  4. 最终可以实现合理设置了容器、宿主机、java程序三者的内存的目的

K8S(18)容器环境下资源限制与jvm内存回收的更多相关文章

  1. 容器环境下如何将NuGet包XML文档添加到Swagger

    容器环境下将NuGet包XML文档添加到Swagger 在.NET Core项目开发过程中,为了实现代码复用,我们将可以重复使用的部分拆分成一个个小的NuGet包.这些NuGet包可以在其他系统中复用 ...

  2. Docker容器环境下ASP.NET Core Web API应用程序的调试

    本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Docker容器环境下,对ASP.NET Core Web API应用程序进行调试.在 ...

  3. Docker容器环境下ASP.NET Core Web API

    Docker容器环境下ASP.NET Core Web API应用程序的调试 本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Dock ...

  4. [移动网关]2G环境下资源下载有一定概率失败,客户端日志显示收到403错误

    2G环境下资源下载有一定概率失败,客户端日志显示收到403错误 问题现象: 测试同学在使用联通号码在移动网络环境下,访问连接得到的response_code出现是403,导致资源读取失败表情显示异常. ...

  5. Docker环境下Java应用的最大内存和堆内存的设置

    Docker环境下Java应用的最大内存和堆内存的设置 1.  设置应用允许使用的最大内存 通过docker run(创建一个新的容器并运行)命令中设置-m来进行设置.案例如下所示. docker r ...

  6. Linux下tomcat运行时jvm内存分配

    tomcat运行时jvm内存分配 ⑴开发环境下在myeclipse中配置-Xms256m -Xmx512m -XX:NewSize=64m -XX:MaxNewSize=128m -XX:PermSi ...

  7. 用k8s构建生产环境下应用服务

    1.生成镜像 见https://www.cnblogs.com/mushou/p/9713741.html,把测试成熟的应用添加到tomcat镜像生成新的镜像,用ansible部署到集群的几点服务器中 ...

  8. Ubuntu 18.04 环境下 kubernetes v1.16.2 单机部署说明

    一.安装环境 本次部署使用阿里云ECS 操作系统: Ubuntu  18.04 64位 实例规格: ecs.c6.large 2U4G 二.kubernetes 版本 k8s.gcr.io/kube- ...

  9. Ubuntu 18.04 环境下安装 Matlab2018

    由于实验环境要求,最近在 Ubuntu 18.04 上安装了 Matlab2018b , 这里简单记录过程. (1) 首先是获取对应的 Matlab2018b 的安装包,这里笔者是在一个外国的网站上获 ...

随机推荐

  1. Python - Asyncio模块实现的生产消费者模型

    [原创]转载请注明作者Johnthegreat和本文链接 在设计模式中,生产消费者模型占有非常重要的地位,这个模型在现实世界中也有很多有意思的对应场景,比如做包子的人和吃包子的人,当两者速度不匹配时, ...

  2. 大话Spark(5)-三图详述Spark Standalone/Client/Cluster运行模式

    之前在 大话Spark(2)里讲过Spark Yarn-Client的运行模式,有同学反馈与Cluster模式没有对比, 这里我重新整理了三张图分别看下Standalone,Yarn-Client 和 ...

  3. HDOJ-1114(完全背包模板题)

    Piggy-Bank HDOJ-1114 本题就是完全背包的模板题,注意复习一下关于背包九讲中的问什么这里使用的是顺序遍历. 还需要注意的一个问题就是初始化的问题,dp[0]初始化为0,其他的初始化为 ...

  4. 浅析MyBatis(一):由一个快速案例剖析MyBatis的整体架构与运行流程

    MyBatis 是轻量级的 Java 持久层中间件,完全基于 JDBC 实现持久化的数据访问,支持以 xml 和注解的形式进行配置,能灵活.简单地进行 SQL 映射,也提供了比 JDBC 更丰富的结果 ...

  5. CF1149C Tree Generator™

    一.题目 点此看题 二.解法 话说老师给的课件是错的啊,把我坑了好久,我手玩样例才玩出来,最后只能去看洛谷题解了. 本题是树是用一个括号序列给出的,你要知道的是:( 代表递归下去到一个新节点,) 表示 ...

  6. Spring Boot 启动过程

    一切从SpringApplication.run()开始,最终返回一个ConfigurableApplicationContext 构造了一个SpringApplication对象,然后调用它的run ...

  7. golang 二维平面求多重遮挡三角形总面积

    解决问题描述:二维平面有很多三角形错落,可能会相互叠加落在一起,也可能互相远离.目标求出这些三角形的总占地面积. 我最开始想的解决方案是用总面积-总重叠面积 = 总占地面积.后来实现起来发现当面临多次 ...

  8. js前端技术

    一.前端技术 1.HTML HTML(hypertext markup language)超文本标记语言,不同于编程语言. 超文本就是超出纯文本的范畴,描述文本的颜色.大小.字体. HTML由一个个标 ...

  9. 【odoo14】第二十一章、性能优化

    通过odoo框架,我们可以开发大型且复杂的应用.良好的性能是实现这一目标的基础.本章,我们将探讨如何提高应用性能.同时,我们也会讲解找出影响性能的因素. 本章包含以下内容: 记录集的预读取模式 将数据 ...

  10. java实现一个点餐系统

    转载于blog.csdn.net/weixin_44219955 项目大体框架 菜品类(菜品id,菜品名,菜品类型,上架时间,单价,月销售,总数量) 管理员类(管理员id,账号,密码) 客户类(客户i ...