写点什么

JVM 垃圾回收原理 / 秒杀系统设计

发布于: 2020 年 08 月 05 日

Date:  2020/8/4   V1.0

    Author:Jessie



1. JVM垃圾回收原理



垃圾对象的识别

JVM垃圾回收采用“可达性分析算法”进行垃圾对象的识别。  线程栈帧的局部变量、方法区的静态变量,进行引用标记;无标记的对象为可回收的垃圾对象。

垃圾对象回收方法

如图所示:

1.   清理: 将垃圾对象占用的空间标记为空闲,记录在空闲列表中,当有新建对象时,则直接分配使用;

2.   压缩:从堆空间开头开始,将存活的对象拷贝在一段连续的内存空间中,剩余连续的空闲空间。

3.   复制:将堆空间分成两部分,只在其中一部分创建对象,当对象使用完后,可用对象复制到另一空间中。



JVM分代垃圾回收

 JVM内存管理

JVM内存管理分:新生代和老年代、持久代。

1.   新生代(Young Gen):主要存放新创建的对象,内存大小相对会比较小,垃圾回收会比较频繁。

1)   新生代又分三个区Eden区、Survivor区:From \to ;

2)   创建对象区:Eden:一旦满了后激动一次新生代的回收;

3)   垃圾回收器进行垃圾回收时,扫描Eden和From,如果对象仍然存活,则复制到To,如果To已经满,则复制到老年代。

4)   扫描完毕后,JVM将Eden和From清空,然后交换From和to的角色(即下次垃圾回收时会扫描Eden和to。这么做主要是为了减少内存碎片的产生。

我们可以看到:Young Gen垃圾回收时,采用将存活对象复制到空的Suvivor Space的方式来确保尽量不存在内存碎片,采用空间换时间的方式来加速内存中不再被持有的对象尽快能够得到回收。

2.   老年代(Tenured Gen)老年代主要存放JVM认为生命周期比较长的对象(经过几次的Young Gen的垃圾回收后仍然存在),内存大小相对会比较大,垃圾回收也相对没有那么频繁(譬如可能几个小时一次)。

老年代主要采用压缩的方式来避免内存碎片(将存活对象移动到内存片的一边,也就是内存整理)。当然,有些垃圾回收器(譬如CMS垃圾回收器)出于效率的原因,可能会不进行压缩。

3.    持久代(Perm Gen):持久代主要存放类定义、字节码和常量等很少会变更的信息。



JVM垃圾回收器算法



1.  串行回收器

设计用于单线程环境(例如32位或Windows)和以及用于比较小的堆。此收集器会在自己工作的时候冻结所有应用程序线程,所以可能不适合服务器环境。

2.  并行回收器

多核时代,并行垃圾回收,这是JVM的默认收集器。最大的优点是使用多线程来扫描和压缩堆。并行收集器同样有个缺点就是在它执行 minor或者 full 垃圾回收时将会停止所有的应用程序线程(stop-the-world)。

3.  并发回收器CMS(配置太多)

CMS:Concurrent Mark Sweep,并发标记清除,是一种以获取最短回收停顿时间为目标的收集器。

初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,并发标记阶段就是进行GC Roots Tracing的过程,而重新标记阶段则是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始阶段稍长一些,但远比并发标记的时间短。

并发收集、低停顿,配置很多。

 

4.  G1回收器:

Java 1.7 开始更新为G1回收器。(未来主流)

G1收集器仍然可以通过并发的方式让Java程序继续运行;

G1重新定义了堆空间,打破了原有的分代模型,将堆划分为多个大小相等的独立区域(Region)。这么做的目的是在进行收集时不必在全堆范围内进行G1提供了接近实时的收集特性



参考资料

李智慧架构《JVM虚拟机原理》

https://blog.csdn.net/jisuanjiguoba/article/details/80156781

https://www.cnblogs.com/kakatadage/p/12213233.html

https://www.tinymind.net.cn/articles/a1bbc49fb00e58



2. 秒杀系统设计

https://xie.infoq.cn/article/46556772c57b1dbfe0b715c95



秒杀业务的影响

1.   正常业务影响:

网站秒杀业务会堆正常网站业务流程带来影响。

2.  服务器影响:

秒杀活动是一种非运营常态的营销手段,带来并发访问用户是平时运营的数百倍甚至上千倍。应对这些最高并发访问量需要的服务器是大部分用不着的。

 

秒杀系统的挑战

1.   对现有网站业务的冲击

秒杀活动时间短、访问量特大,与原有系统部署一起,可能会导致网站的瘫痪。

2.   高并发下的应用、数据库负载

用户不停刷新浏览器页面,如果常规的架构:应用服务器-数据库服务器,会造成极大的复杂压力。

3.   突然增加的网络及服务器带宽

商品图片的不断刷新加载,网络带宽超过了平时使用限度。

4.   防止有漏洞直接下单

如果能绕过前面秒杀页面,直接绕到后面下单URL,则存在不等秒杀直接下单的漏洞。

秒杀系统的应对思路

1.   秒杀系统独立部署

独立部署系统、还可以独立域名,与业务网站隔离,秒杀系统不会对现有系统造成任何影响。

2.   秒杀商品页面静态化

秒杀商品页面内容全部静态化一个页面,不需要访问数据库和应用服务器。

3.   租借临时的秒杀活动网络带宽

秒杀商品页面缓存在CDN,租用新的出口带宽和CDN,应对最大并发访问。

4.   动态生成随机下单页面url

下单页面需要加动态token,秒杀系统开始时进行随机生成。只有正式开始秒杀,才能有动态url生成和处理。

秒杀系统的设计架构

1.   页面、逻辑一起都要简化;

2.   静态页面全部缓存到CDN、方向代理服务器和用户浏览器。避免到达应用服务器。

3.   秒杀开始按钮点亮,单独用轻量级JS脚本定时动态生成,单独部署JS服务集群,对动态脚本定时更新随机版本号,控制实时秒杀开始。



4.   从入口控制下单数量,利用全局计数器控制可以下单地数量,比如每台下单服务器只接收前10个下单请求,后续全部提示活动结束。(每个环节的阀门控制)。例如:





整体架构如下:

1.   CDN服务器:缓存秒杀商品(压缩合并图片)静态文件;根据实际并发数量,计算需要的服务器和出口带宽。

2.   JS服务器集群:动态生成轻量级地JS文件,控制实际秒杀开始。(按钮点亮)

3.   秒杀商品页面服务器:反向代理服务器

4.   下单服务集群:处理下单请求控制和更新全局计数器。这里会控制每台服务器的请求接受数量,超过则直接提示结束,避免给后端的压力。

5.   订单处理子系统:正常处理后续的订单和支付业务。



服务器、带宽准备举例:





发布于: 2020 年 08 月 05 日阅读数: 57
用户头像

还未添加个人签名 2018.08.21 加入

码过代码、做过产品;擅长码字、演讲、认真做事之人。

评论

发布
暂无评论
JVM垃圾回收原理/秒杀系统设计