JVM 垃圾回收与秒杀系统设计
请简述 JVM 垃圾回收原理。
标记(算法):
-判定对象是否存活
-根搜索算法(GC Roots Tracing)
从线程栈帧中的局部变量,或方法区的静态变量触发,标记这些变量引用的对象,然后继续标记这些对象引用的其他对象。没有被标记的对象就是可回收的垃圾对象
-GC Roots
虚拟机栈(栈帧中的本地变量表)中的引用的对象。
方法区中的类静态属性引用的对象。
方法区中的常量引用的对象。
本地方法栈中 JNI(即一般说的 Native 方法)的引用的对象。
回收(算法):
-清理:待清理的标记为空闲
-整理:让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存
-复制:内存分为大小相同的两块,使用一块,然后将标记的对象移动到另一块儿
分代回收:
-新生代:每次垃圾收集时都发现有大批对象死去,只有少量存活,选用复制算法
1 个 Eden 区和 2 个 Survivor 区(from/to)
回收:eden -> to & from -> to/old & to 变成 from
-老年代:对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清理”或“标记-整理”算法来进行回收。
回收器:
stop-the-world
串行回收器:单个垃圾回收线程 stop-the-world
并行回收器:多个垃圾回收线程 stop-the-world
并发回收器 CMS:
初始化标记(stop-the-world):只标记根相关的 ,很快
应用和并发标记并发执行
重标记(stop-the-world):浪费了部分资源
并发清理
G1 回收器(GCPause):
-stop-the-world:-XX:MaxGCPauseMillis
-多个 Region,每一次回收都是回收 N 个 Region
-每个 Region 被标记成 E、S、O、H
设计一个秒杀系统,主要的挑战和问题有哪些?核心的架构方案或者思路有哪些?
技术挑战
瞬间高并发
带宽耗尽
类似 ddos 攻击
秒杀器等工具的请求
跳过秒杀页面,直接下单
设计原则
页面静态化
并发控制:设置阀门,只放一部分人进入
简化流程:减少分支、数据库查询;下单成功为秒杀成功标志
前端优化:YSLOW 原则
实现思路:全链优化。。。
秒杀页面:页面的变更,判断秒杀开始
静态页面;
INotify 同步 js;
js 不走缓存;
根据 js 数组中的值判断是否开始
秒杀静态页面优化
图片合并偏移、压缩、精简
下单页面优化
并发控制:三道阀门
限制进入秒杀页面
限制进入下单页面
限制进入支付系统
秒杀器
秒杀的 Detail 页面:
随机 url;秒杀前短时间放出;访问上限控制
下单页面:
订单 ID 随机;
不能跳过 Detail 页面
秒杀带随机 Token 作为 URL
访问上限控制
WebServer 调优
下单页面优化
砍数据库访问;
精简流程
采用内存缓存“秒杀 offer 数据”、“支付”信息
交易系统性能优化
二跳页面优化
应急预案
备用服务器
保住主要核心应用
万能出错页面
评论