一文彻底搞懂 CMS GC 参数配置
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文彻底搞懂 CMS GC 参数配置相关的知识,希望对你有一定的参考价值。
参考技术A近期整理多个 HBase 集群的 JVM 参数,发现都是默认的 CMS GC 配置,如何调优 JVM 参数就成了一个绕不过的话题。因此,为了寻求一个 CMS GC 的 JVM 合理参数配置,笔者参考多篇社区文章及相关博客,总结了一些 CMS 相关的知识点,以及一套基于 CMS 的 JVM 参数配置。
CMS(Concurrent Mark Sweep,并发-标记-清除)是目前最常用的 JVM 垃圾回收器,这里不解释 CMS 的工作过程,只记录一些基础要点以帮助理解后面的内容:
经过理解各个参数的含义及取值影响,总结了以下的 JVM 参数配置,可以几乎不用调整使用:
如果是 64G 及以上的大堆,-Xmn 可以调整到2g,其他参数不变或微调。下面对一些重要的 JVM 参数介绍说明。
以下参数解析都建立在使用 CMS GC 策略基础上,这里使用 CMS GC 表示老年代垃圾回收,Young GC 表示新生代垃圾回收。
① -Xmx, -Xms, -Xmn
-Xmx、-Xms 分别表示 JVM 堆的最大值,初始化大小。-Xmx 等价于-XX:MaxHeapSize,-Xms 等价于-XX:InitialHeapSize。
-Xmn表示新生代大小,等价于-XX:MaxNewSize、-XX:NewSize,这个参数的设置对 GC 性能影响较大,设置小了会影响 CMS GC 性能,设置大了会影响 Young GC 性能,建议取值范围在1~3g,比如32g堆大小时可以设为1g,64g堆大小时可以设为2g,通常性能会比较高。
② -Xss
表示线程栈的大小,等价于-XX:ThreadStackSize,默认1M,一般使用不了这么多,建议值256k。
③ -XX:SurvivorRatio
新生代中 Eden 区与 Survivor 区的比值,默认8,这个参数设置过大会导致 CMS GC 耗时过长,建议调小,使得短寿对象在Young区可以被充分回收,减少晋升到Old区的对象数量,以此提升 CMS GC 性能。
④ -XX:+UseParNewGC, -XX:+UseConcMarkSweepGC
分别表示使用并行收集器 ParNew 对新生代进行垃圾回收,使用并发标记清除收集器 CMS 对老年代进行垃圾回收。
⑤ -XX:ParallelGCThreads, -XX:ParallelCMSThreads
分别表示 Young GC 与 CMS GC 工作时的并行线程数,建议根据处理器数量进行合理设置。
⑥ -XX:MaxTenuringThreshold
对象从新生代晋升到老年代的年龄阈值(每次 Young GC 留下来的对象年龄加一),默认值15,表示对象要经过15次 GC 才能从新生代晋升到老年代。设置太小会严重影响 CMS GC 性能,建议默认值即可。
⑦ -XX:+UseCMSCompactAtFullCollection
由于 CMS GC 会产生内存碎片,且只在 Full GC 时才会进行内存碎片压缩(因此 使用 CMS 垃圾回收器避免不了 Full GC)。这个参数表示开启 Full GC 时的压缩功能,减少内存碎片。
⑧ -XX:+UseCMSInitiatingOccupancyOnly , -XX:CMSInitiatingOccupancyFraction
-XX:CMSInitiatingOccupancyFraction 表示触发 CMS GC 的老年代使用阈值,一般设置为 70~80(百分比),设置太小会增加 CMS GC 发现的频率,设置太大可能会导致并发模式失败或晋升失败。默认为 -1,表示 CMS GC 会由 JVM 自动触发。
-XX:+UseCMSInitiatingOccupancyOnly 表示 CMS GC 只基于 CMSInitiatingOccupancyFraction 触发,如果未设置该参数则 JVM 只会根据 CMSInitiatingOccupancyFraction 触发第一次 CMS GC ,后续还是会自动触发。建议同时设置这两个参数。
⑨ -XX:+CMSClassUnloadingEnabled
表示开启 CMS 对永久代的垃圾回收(或元空间),避免由于永久代空间耗尽带来 Full GC。
在线工具
GC在线参数检查与优化: https://xxfox.perfma.com
GC在线日志分析: https://gceasy.io/
参考文档
http://hbasefly.com/2016/08/09/hbase-cms-gc/
https://mp.weixin.qq.com/s/gddff77gPdi5s2Hc9HBtcg
https://mp.weixin.qq.com/s/euey8visBvINQNOF0AiACQ
目前我们主要使用 CMS,其实比较大的heap建议使用 G1 垃圾回收器,关于 G1 后文我们会进行介绍总结。欢迎留下你的见解。
往期文章精选
◆ Apache Hudi 0.5.1版本重磅发布
◆ 贝壳找房基于 Flink 的实时平台建设
◆ 网易基于 HBase 的最佳实践
◆ 小米流式平台架构演进与实践
如果您喜欢这篇文章,点【在看】与转发都是一种鼓励,期待得到您的认可 ❥(^_-)
一文彻底搞懂 Tomcat !
微信搜索逆锋起笔
关注后回复编程pdf
领取编程大佬们所推荐的 23 种编程资料!
Tomcat是做Java Web开发时部署服务最受欢迎的容器,关于它的运行机制和调优参数本文进行一定的整理。
Architecture
配置
<?xml version= '1.0' encoding= 'utf-8'?>
<Server port= "8005" shutdown= "SHUTDOWN">
<Listener className= "org.apache.catalina.core.AprLifecycleListener" />
<Listener className= "org.apache.catalina.core.JasperListener" />
<Listener className= "org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className= "org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className= "org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<Service name= "Catalina">
<Connector port= "8080" protocol= "HTTP/1.1"
connectionTimeout= "20000"
redirectPort= "8443" />
<Connector port= "8009" protocol= "AJP/1.3" redirectPort= "8443" />
<Engine name= "Catalina" defaultHost= "www.testwebapp.com">
<Host name= "www.testwebapp.com" appBase= "webapps"
unpackWARs= "true" autoDeploy= "true">
</Host>
</Engine>
</Service>
</Server>
-
Server组件,顶级元素,是Tomcat的运行实例,一个JVM只包含一个Server组件 -
Listener,内置的一些监听器,可以帮我们在发生特定事件的时候起到相应的作用 -
Service组件,可以有多个,它是将Connector组件与Container组件包装组合在一起,对外提供服务。该组件中会包含多个Connector组件组件以及一个Container组件。 -
Connector组件,隶属于Service组件,可以有多个,如这里分别监听了HTTP/1.1西诶呦和AJP/1.3协议并分别绑定两个独立端口。将Socket请求过来的数据,都封装成Request请求对象,同时将该请求对象传递给容器进行下一步的处理。 -
Engine引擎,用来管理多个站点, 一个Service最多只能有一个Engine -
Host,代表一个站点,也可以叫虚拟主机。它指定具体的服务的部署位置,如appBase指定了代码的部署文件夹路径,并且是否支持自动部署和自动解压War包 -
Context :代表一个应用程序,即为我们开发的一个war服务在webapp目录下的各个应用,或者一个WEB-INF 目录以及下面的web.xml 文件; -
Wrapper :每个Wrapper 封装着一个servlet。
HTTP请求处理流程
-
1、在用户在浏览器中点击页面进行数据请求后,Tomcat本机默认端口8080接收到数据请求,被在那里监听的Coyote HTTP/1.1 Connector获得;
-
2、Connector把封装好的Request请求交由其所在的Service的Engine来处理,并等待Engine的回应;
-
3、Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host;
-
4、Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有的Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context去处理);
-
5、path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URL PATTERN为*.jsp的Servlet,对应于JspServlet类;
-
6、构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost().执行业务逻辑、数据存储等程序;
-
7、Context把执行完之后的HttpServletResponse对象返回给Host;
-
8、Host把HttpServletResponse响应对象返回至Engine;
-
9、Engine将HttpServletResponse响应对象返回至Connector;
-
10、Connector将HttpServletResponse响应对象返回给客户端的浏览器。
Connector
Connector是Tomcat的核心组件,从这里 可以看到各种Connector的对比。主要参数如下:
-
maxThreads 默认200,表示任意时刻能够并行执行的最大线程数
-
minSpareThreads 默认值10,表示任意时刻处于running状态的线程的最小值,包括idle和active两种状态的线程
-
maxConnections Tomcat能够接收和处理的并发连接的最大值,超过这个值后的连接将会被放入一个queue中,等待有空闲线程调用。默认值10000(NIO/NIO2)或8192(APR/native)
-
acceptCount 默认值100,当没有空闲线程的时候新的TCP请求连接都会放入这个一个queue中,这个是队列的长度值,超过就直接拒绝请求了
-
connectionTimeout 单位毫秒,超过这个值Connector将会释放这个idle的连接
Connection Refused
错误。此时应该对线程池的容量做适当调整, 但也不能调整过大,防止服务器负载升高。
Executor
RejectedExecutionException
错误。
线程模型
-
Acceptor:接收socket线程,这里虽然是基于NIO的connector,但是在接收socket方面还是传统的serverSocket.accept()方式, 获得SocketChannel对象,然后封装在一个tomcat的实现类org.apache.tomcat.util.net.NioChannel对象中。然后将NioChannel对象封装在一个PollerEvent对象中,并将PollerEvent对象压入events queue里。这里是个典型的生产者-消费者模式,Acceptor与Poller线程之间通过queue通信,Acceptor是events queue的生产者, Poller是events queue的消费者。 -
Poller:Poller线程中维护了一个Selector对象,NIO就是基于Selector来完成逻辑的。在connector中并不止一个Selector, 在socket的读写数据时,为了控制timeout也有一个Selector。可以先把Poller线程中维护的这个Selector标为 主Selector 。Poller是NIO实现的主要线程。首先作为events queue的消费者, 从queue中取出PollerEvent对象,然后将此对象中的channel以 OP_READ 事件注册到 主Selector 中,然后主Selector执行select操作, 遍历出可以读数据的socket,并从Worker线程池中拿到可用的Worker线程,然后将socket传递给Worker。 -
Worker :Worker线程拿到Poller传过来的socket后,将socket封装在SocketProcessor对象中。然后从Http11ConnectionHandler 中取出Http11NioProcessor对象,从Http11NioProcessor中调用CoyoteAdapter的逻辑。
References
https://www.datadoghq.com/blog/tomcat-architecture-and-performance/
https://cloud.tencent.com/developer/article/1103077
https://blog.csdn.net/Diamond_Tao/article/details/87389315
https://zhuanlan.zhihu.com/p/85448047
逆锋起笔
是一个专注于程序员圈子的技术平台,你可以收获最新技术动态
、最新内测资格
、BAT等大厂大佬的经验
、增长自身
、学习资料
、职业路线
、赚钱思维
,微信搜索逆锋起笔
关注!
❤️ 给个在看,是最大的支持❤️
以上是关于一文彻底搞懂 CMS GC 参数配置的主要内容,如果未能解决你的问题,请参考以下文章