写点什么

架构师训练营第九周课后作业

用户头像
Gosling
关注
发布于: 2020 年 11 月 22 日
1.请简述 JVM 垃圾回收原理

JVM 的运行时数据区域大致分为:程序计数器、Java 虚拟机栈、本地方法栈、Java 堆、方法区、运行时常量池(属于方法区)和直接内存。

在运行时可以被 JVM 处理的内存垃圾回收主要是 Java 堆和 Java 虚拟机栈。

首先 Java 虚拟机栈是线程独享的内存,它的生命周期和线程一样。当栈帧出栈后,这部分的声明的引用占用的内存就自动释放。

重点是堆内存,引用真正的对象内存是在堆中,一般有几种方式来判断这个对象是否还需要存活。

1.引用计数法

这种方法在大部分场景下都比较有效,但是很难解决对象之间相互循环引用,所以这种方式没有被 JVM 采用。

2.可达性搜索算法

JVM 采用的是通过 GC Roots 作为起点,从这些节点开始向下搜索,所经过的路径称为引用链,当对象没有引用链到达 GC Roots 时,则判断这是需要被回收的对象。

GC Roots 对象一般包括下面几种:

  • 虚拟机栈中引用的对象

  • 方法区中的类静态属性引用的对象

  • 方法区中的常量引用对象

  • 本地方法栈中 JNI 引用的对象

当对象被判断需要被回收,会被垃圾回收线程标记一次,这时候会判断是否要调用对象的 finalize 方法,如果判断是需要执行,则对象进入一个待回收队列 F-Queue。稍后垃圾回收线程会对 F-Queue 中的线程进行第二次标记,如果这时候还是没有该对象到达 GC Roots 的引用链,则最终被垃圾回收掉内存。


这种标记清除算法是一种最基础的垃圾回收算法,后续迭代出了复制算法、标记整理算法,分代回收算法都是在这个基础上产生的。

我们常说的 From 区和 To 区的来回复制,就是用的复制算法。

2.设计一个秒杀系统,主要的挑战和问题有哪些?核心的架构方案或者思路有哪些?

设计一个秒杀系统,最主要的挑战就是高并发和超售的问题。

高并发是由于秒杀吸引大量用户在一个比较集中的时间段内高频次的对服务器进行请求,短时间内会超出系统正常的负荷,导致系统会出现崩溃的可能,同时高并发下会涉及到线程安全,导致一不注意出现商品超售的情况。

整个实现秒杀系统的核心思路是有这么几方面:

(1)系统隔离

应对活动的秒杀页面可以和正常的商品页做成两个分离的系统,这样当因为活动增加的流量上升时,分离出的秒杀系统会承担这部分流量,而正常的商品页面不会直接受到太大影响,其次分离出的系统也非常适合做水平扩展,而且可以砍掉一些不必要的前端功能,使之加载更加效率。如果不做系统的隔离,这些问题都需要花费更多精力来处理。

(2)页面静态化

由于我们要秒杀的商品都是事先确定好的,所以我们不需要实时去动态生成前端页面的内容(一般前后端分离,动态数据会根据后端数据库返回的数据填充生成完整的页面),可以把要秒杀的商品直接生成静态的内容,这样只是单纯打开秒杀的前端页面时就减少了对数据库的压力。

(3)CDN 缓存

由于页面都是静态,非常适合做 CDN 缓存,把页面分发到 CDN 服务,尤其是图片和 JS,CSS 这些资源。可以极大减少对服务器带宽的压力。

(4)分层限流

可以把从秒杀开始后,进入秒杀页面、点击购买进入下单页面、实际支付请求分成三级来处理我们的流量,用漏斗的方式一层一层把最复杂的逻辑放到后面来处理,前面通过限流计数器把人数控制住,这样实际在执行后续业务操作的并发量并不会太大。

(5)分布式锁

由于最后实际进入下单页面的用户并不会太多,所以我们这里可以用分布式锁来控制超售问题,例如用 Redis 的原子操作性,把用户的下单进行异步化队列处理,当超过剩余件数,就执行退款操作。


其总体思路就是让对业务的请求量压力通过各种方式分散掉,不让我们正常的业务系统、核心的业务数据库被流量冲垮。


用户头像

Gosling

关注

这个家伙很懒,只留下这一句话 2017.10.28 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第九周课后作业