K8S容器环境下资源限制与jvm内存回收
一、k8s中的java资源限制与可能的问题
与以前单机跑单服务的情况相比,在k8s、docker容器化环境下的宿主机内存、cpu相对更大,所以当运行java类程序的时候,就必然有必要对容器进行内存限制,否则以java默认参数启动,一个程序就可能吃掉你四分之一的内存
但是怎么限制,就是一个值得考虑的问题了。
方案1:通过JVM的Xms和Xmx
参数限制
java -Xms2048m -Xmx2048m -jar register.jar
在非容器化时,最常规的方案;在容器化中,也经常使用向容器传递环境变量的方式,通过控制这两个参数来控制服务的内存使用量
在网上通常的jvm调优方案中,也通常会要求把这两个参数设置为相等(可认为属于调优共识),来较小FGC的频率和提高性能
但是在容器化情况下(假设xmx=xms=4G),存在的问题是:
A 内存不释放问题:
- java容器运行后,会慢慢的用到设置的内存上限4G
- 由于还有其他的开销,一般会达到6G左右,并且不会释放
- 你会发现你宿主机或集群的内存,只升高不降低,除非你重启容器
B 参数设置多少的问题:
- 由于给它设置的内存,它总会用完,不好确定到底给它多少内存
- 给多了不够用,给少了GC频繁
- 有些人要说GC调优确定最合适内存,但这个因素不可控
所以这样,宿主机或集群的总内存,必须得大于你设置的所有容器的内存上限总和才保险
方案2:通过容器的requests和limits
参数控制
docker容器和k8s都可以通过参数限制分配给容器的内存大小,同样假设分配了4G,问题会是
- 容器资源隔离的原因,容器中看到的内存大小=宿主机的内存大小
- 容器中的java服务,不知道自己被限制了内存,会按默认的1/4申请内存
- 由于对容器进行了内存限制,所以极大概率该容器运行一段时间后会被重启
方案3:容器参数和JVM参数共用
较可行的方案是两边的参数一起使用,只是要注意容器限制的内存要比jvm设置的大(1-2)G,因为前面说了JVM设置的4G,实际可能会用到6G。
但是共用也没有彻底解决第一个方案中的问题,即:
- 给java服务到底分配多少内存
- 申请的内存不释放,导致宿主机内存总量上限问题
- 多个地方设置内存参数,麻烦
二、解决问题三板斧
主要参考的三个博客
参考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)配置容器的资源限制参数
在前两条的基础上,最后在配合容器的资源限制功能后,就能做到
- 限制容器的内存上限
- 容器内的jvm服务,能根据资源限制来申请内存
- 由于jvm会释放内存,所以可先设一个较大值,经过长期观察,可以确定该服务的常规内存水平
- 最终可以实现合理设置了容器、宿主机、java程序三者的内存的目的
转载自:https://www.cnblogs.com/noah-luo/p/14721172.html
K8S容器环境下资源限制与jvm内存回收的更多相关文章
- K8S(18)容器环境下资源限制与jvm内存回收
K8S(18)容器环境下资源限制与jvm内存回收 目录 K8S(18)容器环境下资源限制与jvm内存回收 一.k8s中的java资源限制与可能的问题 方案1:通过JVM的Xms和Xmx参数限制 方案2 ...
- 容器环境下如何将NuGet包XML文档添加到Swagger
容器环境下将NuGet包XML文档添加到Swagger 在.NET Core项目开发过程中,为了实现代码复用,我们将可以重复使用的部分拆分成一个个小的NuGet包.这些NuGet包可以在其他系统中复用 ...
- Docker容器环境下ASP.NET Core Web API应用程序的调试
本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Docker容器环境下,对ASP.NET Core Web API应用程序进行调试.在 ...
- Docker容器环境下ASP.NET Core Web API
Docker容器环境下ASP.NET Core Web API应用程序的调试 本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Dock ...
- [移动网关]2G环境下资源下载有一定概率失败,客户端日志显示收到403错误
2G环境下资源下载有一定概率失败,客户端日志显示收到403错误 问题现象: 测试同学在使用联通号码在移动网络环境下,访问连接得到的response_code出现是403,导致资源读取失败表情显示异常. ...
- Docker环境下Java应用的最大内存和堆内存的设置
Docker环境下Java应用的最大内存和堆内存的设置 1. 设置应用允许使用的最大内存 通过docker run(创建一个新的容器并运行)命令中设置-m来进行设置.案例如下所示. docker r ...
- JVM内存回收机制简述
JVM内存回收机制涉及的知识点太多了,了解越多越迷糊,汗一个,这里仅简单做个笔记,主要参考<深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)> 目前java的jdk默认虚拟机为H ...
- JVM内存回收机制——哪些内存需要被回收(JVM学习系列2)
上一篇文章中讨论了Java内存运行时的各个区域,其中程序计数器.虚拟机栈.本地方法栈随线程生灭,且创建时需要多少内存,基本上在译期间就决定的了,所以在内存回收时无需特殊的关注.而堆和方法区则不同,首先 ...
- Java基础-JVM内存回收
Sun的JVMGenerationalCollecting(垃圾回收)原理是这样的:把对象分为年青代(Young).年老代(Tenured).持久代(Perm),对不同生命周期的对象使用不同的算法.( ...
- JVM内存回收机制
1. JVM内存回收机制简述 http://www.cnblogs.com/lzrabbit/p/3826738.html
随机推荐
- 纪念JDBC
技术总是在不断更新变化的,尤其是在IT编程领域. 有时候我们理所当然的用着现成的框架,以至于用的太过于顺手,更要时不时的骂一句: 什么垃圾框架?我家狗都不会用! 如果那些被拍死在沙滩的"前浪 ...
- delphi IDE 控件居中的方法
- sshd命令-测试sshd_config配置是否正确
sshd命令来自于英文词组"SSH daemon"的缩写,其功能是用于openssh服务器守护进程.openssh套件能够为两台主机之间建立加密的.可信任的数据通信服务,是rlog ...
- Windows—通过Navicat导入MySQL示例数据库employees
Navicat是一套可创建多个连接的数据库管理工具,用以方便管理 MySQL.Oracle.PostgreSQL.SQLite.SQL Server.MariaDB .MongoDB 等不同类型的数据 ...
- C++ 单例模式以及内存管理
引用: https://zhuanlan.zhihu.com/p/37469260 https://www.cnblogs.com/xiaolincoding/p/11437231.html http ...
- ABC 340
忘记打了,VP 了一把,前五题都是板子. F 题意:坐标系上给定一个整点 \((x,y)\),求另一个整点 \((a,b)\),满足 \((0,0),(x,y),(a,b)\) 组成的三角形面积为 \ ...
- Js中Reflect对象
Js中Reflect对象 Reflect是ES6起JavaScript内置的对象,提供拦截JavaScript操作的方法,这些方法与Proxy对象的handlers中的方法基本相同. 描述 Refle ...
- Java集合框架学习(六) LinkedList详解
LinkedList介绍 ArrayList与LinkedList都是List接口的实现类,因此都实现了List的所有未实现的方法,只是实现的方式有所不同. LinkedList是采用链表的方式来实现 ...
- Java集合框架学习(二) HashSet详解
HashSet介绍 这个类实现了Set接口,背后是一个hash table(实际上是个HashMap 实例) .它不保证元素的迭代顺序.尤其是,随着时间推 移它不保证某一元素的位置不变.这个类是非线程 ...
- Auxiliary Set题解
F Auxiliary Set 树上LCA + DFS 注意一下输出格式! #include<bits/stdc++.h> using namespace std; const int N ...