JVM的STW机制及调优案例

探讨STW(stoptheworld)现象对应用性能的影响及如何通过合理配置JVM参数减少全局暂停时间,提升用户体验。

STW(stop the world)是什么
1、stop the world指的是GC事件发生过程中,会产生应用程序的停顿。停顿产生时整个应用程序线程都会被暂停,没有任何响应, 有点像卡死的感觉,这个停顿称为STW。Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互;这些现象多半是由于gc引起。

(1)可达性分析算法中枚举根节点(GC Roots)会导致所有Java执行线程停顿。
① 分析工作必须在一个能确保一 致性的快照中进行

② 一致性指整个分析期间整个执行系统看起来像被冻结在某个时间点上

③ 如果出现分析过程中对象引用关系还在不断变化,则分析结果的准确性无法保证

(2)被STW中断的应用程序线程会在完成GC之后恢复,频繁中断会让用户感觉像是网速不快造成电影卡带一样, 所以我们需要减少STW的发生。

2、STW事件和采用哪款GC无关,所有的GC都有这个事件。

3、哪怕是G1也不能完全避免stop-the-world情况发生,只能说垃圾回收器越来越优秀,回收效率越来越高,尽可能地缩短了暂停时间。

4、STW是JVM在后台自动发起和自动完成的。在用户不可见的情况下,把用户正常的工作线程全部停掉。开发中不要用System.gc() ;会导致stop-the-world的发生。

为什么需要STW(stop the world)
垃圾回收是根据可达性分析算法,搜索GC Root根的引用链,将不在引用链上的对象当做垃圾回收,设想我们执行某个方法的时候,此时产生了很多局部变量,刚好老年代满了需要进行Full gc,如果不停止线程,垃圾回收正在根据这些局部变量也就是GC Root根搜索引用链,此时这个方法结束了,那么这些局部变量就都会被销毁,这些引用链的GC Root根都销毁了,这些引用当然也成了垃圾对象,这样就会导致在垃圾回收的过程中还会不断的产生新的垃圾。

但是Stop-The-World的结果是比较严重的,如果用户正在浏览你的网站,应用程序突然Stop-The-World,所有线程被挂起,那么用户就会感觉你的网站卡住了,尽管gc时间是比较快的,但是如果并发量比较大,用户感知是比较明显的,会影响用户体验。

JVM调优案例
像京东、淘宝、唯品会这些比较大的电商平台,都属于亿级流量电商,什么是亿级流量电商呢,就是用户在网站上每日的点击是上亿的。这些电商网站后台现在基本都是使用微服务架构搭建的,我们这里就交易系统来分析一下。
————————————————
在这里插入图片描述
对象在内存中的组成,有对象头,实例数据以及对齐填充,其中主要的大小时实例数据占用的,一个对象有很多字段,一个字段占几个字节,一个对象撑死几百个字段,我们这里假设一个订单对象大小1KB,就是1024个字节,这已经算比较大的,一般对象不会超过这么大,

那么接着上面的推算,每秒就会有300KB的订单对象生成,但是我们这里只是估算,下单过程中不仅仅会产生订单对象 ,还会涉及库存,优惠券,积分等其他相关对象,既然是估算,我们肯定要放大一下才可靠。

假设我们这里放大20倍,那么每秒就会有300KB*20也就是6M的对象产生。但是订单系统也不只提供下单操作,可能还有订单查询,订单退款等操作,我们再把这业务放大十倍,那么每秒就会产生60M的对象放入伊甸园区,而且这些对象有一个特点,当我的订单对象一旦生成完毕之后,在堆中生成的对象都会变为垃圾对象,都应该被回收掉。

在工作中项目上线时,都会对这个项目进行一些jvm参数的设置,但是大多数都是随便凭感觉,比如根据机器大小给堆设置个两三G的内存。

我们这里假设机器是4核8G,那么一般可能会给我们虚拟机分配个四五G的内存,就会给堆分配个3G的内存,那么方法区分配256M,单个栈内存分配1M。
在这里插入图片描述
那么这么分配有什么问题呢?如果是一个并发量不大的系统,基本上也不会有什么问题,因为本身也没有多少对象在堆里生成。但是如果是我们上面说的亿级流量系统,就不能简简单单这么设置了,我们来分析一下:
在这里插入图片描述
根据之前我们讲的jvm内存分配,我们可以得知各个区域的所占内存,每秒有60M对象产生进去Eden区,那么13秒就会占满Eden区域,发生minor gc,这些订单对象其中90%其实已经是垃圾对象了,为什么说90%,因为在gc的那一刻,这些对象肯定还有一部分的业务操作还没有完成(方法没有执行完就GC,STW全局暂停),所以他们不会被回收,我们这里假设每次minor gc都有60M对象还不会被回收

​ 那么这60M对象会从Eden区移到S0区域,我们之前的文章有说过对象进入老年代有很多条件,比如较大的对象,这里的60M虽然小于100M,同样会直接被移入老年代,为什么呢?因为还有一个条件是对象动态年龄判断,就是**如果你移动的这批对象超过了Surviror区的50%,会把年龄大于等于这批对象的对象移至到老年代**
​ 那么按现在这种参数设置,每13秒就会有60M的对象被移入老年代,那么大概五六分钟老年代的2G就会被占满,那么老年代一满就要发生full gc,但是full gc使我们最不愿意看到的结果。对于这么大的一个系统,每过五六分钟就发生一次full gc,就会让系统卡顿一次,用户体验很差,这是很大的问题。

jvm调优是为了调优gc,主要就是两个点,一个是减少Full gc的次数,一个是缩短一次Full gc的时间

先来分析一下:我们这个系统其实没有很多会长久存在的对象,也就是老不死的对象,我们放在老年代的那些60M的对象,在一两秒后其实都会变为垃圾对象,在下一次full gc时都会被回收掉,那么我们这种业务场景,完全没必要给老年代设置2G的内存,根本用不到。

我们完全可以把年轻代设置的大一些,我们现在来对jvm参数进行一些更改。
在这里插入图片描述
在这里插入图片描述
当我们进行参数修改之后,你再来按上面的分析来分析这个过程,你会发现一个奇迹效果。

此时需要25秒把伊甸园区放满,放满minor gc后有60M对象不被回收,要移到S0区,这时60M<200M/2,是可以移入S0区域的,下一次伊甸园区再放满做minor gc的时候,这时这60M对象所对应的订单已经生成了,已经变成了垃圾对象,是可以直接被回收的,所以没有什么对象是需要被移入老年代的。

那么这么一设置的话,这个系统是不是正常情况下基本不会再发生full gc了呢?就算发生,也是很久才会一次了。

转自:

https://blog.youkuaiyun.com/weixin_44704538/article/details/108222022

总结一下:
调优就是减少fullgc的次数,什么时候fullgc?
老年代满的时候,所以我们调优就是尽可能让老年代满的周期边长

什么时候对象进入老年代?
1.伊甸园区放不下的对象,直接晋升到老年代。
2.进入Survivor区的一批对象,超过Survivor一半,将大于等于该批对象的移至老年代。
3.长期存活的对象,年龄超过阈值的。(无法改变的)

3是无法避免的,但是1,2我们可以避免。
解决1得办法就是:开发中尽量少new大对象。
解决2的办法就是:不让一批对象超过Survivor一半,把Survivor调大

03-08
### MathPix工具介绍 Mathpix Snipping Tool 是一款强大的数学公式识别工具,从最初的原型发展至今已经历了多次迭代和功能增强[^1]。该工具不仅能处理简单的数学表达式,还可以应对复杂的数学模型以及多行公式,并且支持手写公式的识别。 这款应用程序通过不断的科技创新与用户反馈改进,在学术研究和技术领域赢得了良好声誉,成为许多科研人员不可或缺的工作伙伴之一。除了基本的功能外,Mathpix 还提供了多种高级特性来满足不同用户的特定需求。 ### 使用方法 #### 安装与启动 为了使用 Mathpix Snipping Tool ,首先需要下载安装程序并按照提示完成设置过程。一旦成功安装后即可随时调用此应用来进行截图操作。 #### 截取屏幕上的公式图像 当遇到想要转换成 LaTeX 或 AsciiMath 的图片时,只需打开软件界面按下快捷键(默认为 `Ctrl+Alt+M`),此时鼠标指针会变为十字形状以便于选取目标区域;框选所需部分之后松开按键即刻上传至云端服务器等待进一步分析处理。 #### 获取LaTeX代码片段 经过短暂几秒钟的时间延迟过后,所截获的内容将以纯文本形式显示出来供复制粘贴到其他编辑器当中继续编写文档或是分享给他人查看交流之用。 ```python import pyperclip # 假设已获取到LaTeX字符串 stored_in_variable named latex_code pyperclip.copy(latex_code) print("LaTeX code has been copied to clipboard.") ``` 对于希望深入探索更多可能性的用户来说,可以考虑查阅官方提供的扩展插件——如用于解析Markdown文件内的公式标记语法的库 **mathpix-markdown-it** [^2] ——这将进一步提升工作效率和个人体验感。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值