10w 级的并发场景,JVM 有哪些方面值得优化呢?

科技   2024-11-05 17:07   河北  

大家好,我是华仔。

欢迎加入华仔的星球,你将获得: 专属的中间件专栏 / 1v1 提问 / 简历修改指导/ 学习打卡 / 每月赠书 / 社群讨论

截止目前,累计输出 500w+ 字,讲解图 2000+ 张,还在持续爆肝中.. 后续还会上新更多项目和专栏,目标是打造地表最强中间件星球,戳我加入学习,已有440+小伙伴加入电商实战项目火热更新中,结束时会有简历指导包装,需要的抓紧来

这里说几点,解答一些疑惑,可以认真看下:

1、星球内容只会越来越完善,价格越来越贵,一年时间从69元开始发售到现在已经涨到了199元,还会继续涨价,所以需要抓紧来,越早越受益,别错过

2、只筛选认可且支持我的老铁,我不喜欢白嫖怪,尊重别人就是尊重自己。

3、对于星球年费说下,只是到期后新内容看不到,已经更完的内容相当于一次付费永久看,所以认可我内容的可以放心来,有疑问文末加我好友进行答疑

4、除专栏外,我会提供专属的一对一答疑服务,包括不限于工作中、专栏中遇到的问题,简历修改指导、职业规划服务等。这也是星球的特色服务。

今天我们来简单聊一聊面试中常见的一个问题:要支持 10w 级以上的并发场景, JVM 有哪些方面值得优化呢?

背景

以秒杀为例,大型电商系统会拆分多个微服务,比如订单服务,商品服务,优惠服务,库存服务,支付服务等等。

我们以下单为例,如下是简约版下单流程

一般我们需要结合业务和已有的资源,再去评估 JVM 的 GC 频率来作为参考:

  1. 首先结合业务流程分析,计算我们服务系统每秒产生的对象占用内存大小。
  2. 假设我们采用服务器规模 8C*16G,估算下新生代的空间,大概多久触发 MinorGC。
  3. 为了避免频繁的 Full GC,我们可以重新估算具体需要的机器配置和数量,给 JVM 设置多大内存。

我们先来分析下在 10W TPS 下单场景中,我们每秒产生的对象占用内存大小。

如何选择垃圾回收器?

在选择垃圾回收器的时候,我们需要考虑两个指标:

  • 吞吐量:CPU 在用户应用程序运行的时间/(CPU 在用户应用程序运行的时间+CPU 垃圾回收器运行的时间)。
  • 响应时间:平均每次 GC 的耗时。

目前主流的垃圾回收器配置是新生代采用 ParNew,老年代采用 CMS 组合的方式,虽然在 JDK8 以后更加推荐使用 G1。一般来说,对于延迟敏感的推荐 CMS;在大内存、要求高吞吐推荐 G1。

在电商下单场景中,用户对于些许的延迟可能会比较敏感,所以以下还是以 CMS 使用为例。

然后,我要如何设置 JVM 参数呢?

堆内存大小设置

对于 8G 内存,我们一般设置内存一半给 JVM,正常的 JVM 参数设置如下

-Xms8192M -Xmx8192M Xmn2048M -Xss1M -XX:MMetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:SurvivorRatio=8

这样设置,而在下单场景,大多对象都是短期存活的,这样设置因为动态对象年龄判断原则导致频繁出发 Full GC。
所以可以调整新生代内存大小

-Xms8192M -Xmx8192M -Xmn4086M -Xss1M -XX:MMetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:SurvivorRatio=8

这样就降低了对象频繁进入老年代的问题,实际上很多优化都是围绕着如何减少 Full GC 去做的,就是尽可能把短期存活的对象留在 survivor 里,不要进入老年代,这样就可以在 Minor GC 的时候回收掉这些对象,不会产生 Full GC,从而引发 STW,影响系统性能。

除了新生代大小外,还有什么可以优化呢?

常见 JVM 参数优化

  1. 新生代动态对象年龄:默认设置为 15。本例子中每次 Minor GC 间隔 20s 左右,而在下单场景中,一般对象几秒内就会变成垃圾对象了,像这么长时间都还没被回收的话,其实可以早点放到老年代,这样也不会占用新生代的内存了,比如通过设置参数-XX:MaxTenuringThreshold=5,那么经历过 5 次 Minor GC 后就会进入老年代。

  2. 针对大对象,有时我们会在本地缓存一些不常变化的配置,可结合实际业务评估这些对象大小比如会超过 2M,而且会一直存活保留,那么针对这些对象其实可以直接进入老年代,可以通过设置参数-XX:PretenureSizeThreshold=2M。

  3. 针对 CMS 的碎片整理,因为 CMS 基于标记-清除算法实现,会产生内存碎片,如果这些内存碎片长时间不清理的话,那么老年代的内存可用空间会降低,所以 CMS 也提供了两个参数用于内存碎片的整理:

  • -XX:+UseCMSCompactAtFullCollection,开启内存碎片整理。
  • -XX:CMSFullGCsBeforeCompaction,执行指定次数的 Full GC 后,进行一次内存整理压缩整理的 Full GC。
  1. 元空间大小,Meta 区域的大小一定要指定,如果我们代码类或引入动态生成类的技术超过元空间大小,那么会触发 Full GC,可以通过 jstat 命令查看项目生成类的大小来评估具体设置值,一般设置 256M 够了。

  2. JIT 即时编译,-XX:ReservedCodeCacheSize。JIT 是 JVM 一个非常重要的特性,CodeCahce 存放的就是即时编译器所生成的二进制代码。

  3. JVM 逃逸分析,逃逸分析也是一种优化手段,JVM 如果分析确定一个对象不会逃逸于方法之外,那么这个对象会被分配在栈上,而不是在堆上,这样一定程度上就可以减轻 GC 压力。


最后推荐下两个不错的产品感兴趣的可以
上车了,这里只吸引同频的人,如果加入几分钟
就直接退出的就不要来了,浪费我的名额。

第一个来自码哥的小报童,仅需 19 元,刚开始更新,需要的可以扫码加入。

本专栏内容涵盖 Java 基础、Java 高级进阶、Redis、MySQL、消息中间件、微服务

架构设计等面试必考点、面试高频点。本专栏不只是单纯教大家学会背八股文知识,

更多是结合实际大厂高并发项目的场景,去学习面试技术要点。从面试官的角度去出

发,介绍互联网 Java 流行技术体系各个面试要点。

本专栏适合于准备进阶 Java 后端技术、有面试或提升技术需求,希望学习互联网大

厂 Java 流行技术体系的程序员和面试官,助你拿到名企高薪 Offer。






第二个是我的知识星球,已涨价到 199 元,需要的可以扫码加入,
加入星球后送上面技术小册。

关于星球介绍点击:

超 500 万字详解,从零到一带你彻底吃透 Kafka + RocketMQ

小红书实战





需要续费的扫这个,优惠15元


另外必须要注意的是上车的老铁一定要加我微信
好友,拉你们加入星球专属交流群。


华仔聊技术
聊聊后端技术架构以及中间件源码
 最新文章