架构师训练营第 1 期 第 9 周作业
1. 请简述 JVM 垃圾回收原理
JVM 垃圾回收,简单来说就是把不再使用的对象清理掉,把内存资源释放出来。
基本原理是,给对象是否“有效”打上标记。“无效”对象,将被垃圾回收清理掉。
那如何判断对象是否“有效”呢?
采用的是可达性算法:从 GC root 出发,给其引用的对象标记“有效”,然后继续对这个对象所引用的其他对象也打上标记。当这个树上的所有对象都遍历之后,那些没有被标记的对象就是不可达的对象,也就是“无效”对象。
GC root 的种类有:
线程栈帧中的局部变量
方法区的静态变量
方法区的常量
本地方法栈里被 JNI 引用的对象
标记之后,具体又是如何回收的呢?
算法有 4 种:
标记-清理
把“无效”对象所占的内存空间标记为空闲,可供其他对象申请内存时使用。但会引入内存碎片化的问题。
复制
把内存分为 2 个区域,把“有效”对象挑出来,复制到另一个区域,原来的区域变成全空闲可供分配的状态。这可以避免内存碎片的问题,但缺点是只能用一半的内存。
标记-压缩
先“无效”对象所占的内存空间标记出来,然后把有效内存都移动到一边集中在一起。但缺点就是内存频发拷贝和排序,对性能影响大。
分代收集算法
是上述三种算法的组合。内存被分为几块:年轻代(Eden)、存活代(survivor)、年老代(Old)。
在年轻代,大多数对象生存周期短,只有少数存活,因此用复制算法比较好,复制到存活代。而在年老代,用清理或压缩比较好,因为其存活周期长,不太会频繁发生变化。
2. 设计一个秒杀系统,主要的挑战和问题有哪些?核心的架构方案或者思路有哪些?
挑战和问题:
并发量可能是正常的上百倍
网络带宽可能耗尽
服务器负载过高,可能崩溃,连正常业务也无法处理
数据库也因访问量太大而瘫痪
客户因为点击无响应,不停的刷新页面,造成请求风暴
秒杀页面被 hack 跳过,直接进入下单页面
核销架构思路:
秒杀独立做一套系统,和正常业务隔离
采用阀门机制,当 1000 人点击秒杀后,后面点击的人不再进入,直接显示秒杀结束。100 人下单后,后面的人无法再下单。这样有效过滤掉无效请求,大大减少了后端实际要应对的并发数
优化 webserver 和中间件,去掉不必要的功能,优化配置
把动态页面做成静态页面,可利用各级缓存(CDN、反向代理服务器等)
用第三方 CDN 服务,把图片请求都转到 CDN 上
静态页面极简化设计,去掉不必要的 css,直接写在 html 里,产品列表图片采用一张大图,用 offset 方式区分点击
用动态生成 JavaScript,来控制按钮是否可点击,动态产生 token,能防止下单页面被 hack
评论