第九周作业
一、请简述 JVM 垃圾回收原理。
Java内存主要分为堆区和非堆区(JVM虚拟机栈,本地方法栈,元空间,程序计数器)。
JVM垃圾回收,主要是对堆区的内存进行回收。堆区的内存分为年轻代和永久代。年轻代又进一步划分为Eden区、From区和To区。
MinorGc对Eden区内存的回收。
YangGc对年轻代内存的回收。
MajorGc对老年代内存的回收。
FullGc对整个堆的内存回收。
垃圾回收主要就是对年轻代和永久代的内存进行回收。
回收过程:
1、Eden区内存满时,将Eden区的存活对象,复制到From区,然后清空Eden区。
2、Eden区内存再满时,将Eden区和From区的存活对象复制到To区,然后清空Eden和From区。每次挪动会为存活对象的年龄增1。
1)当年龄达到配置的最大年龄时,进入老年代。
2)当对象往From区或To区负责时,已经放不下当前存活对象,会将年龄大的移到老年代。
3)首次创建的大对象和在MinorGc时在From和To区放不下的对象,会直接进入老年代。
3、老年代对象到达一定比例后触发MajorGC。
怎么判断对象是否存活:
JVM 通过一种可达性分析算法进行垃圾对象的识别,具体过程是:从线程栈帧中的局部变量,或者是方法区的静态变量出发,将这些变量引用的对象进行标记,然后看这些被标记的对象是否引用了其他对象,继续进行标记,所有被标记过的对象都是被使用的对象,而那些没有被标记的对象就是可回收的垃圾对象了。
垃圾回收主要有三种方法:
清理:将垃圾对象占据的内存清理掉,其实 JVM 并不会真的将这些垃圾内存进行清理,而是将这些垃圾对象占用的内存空间标记为空闲,记录在一个空闲列表里,当应用程序需要创建新对象的时候,就从空闲列表中找一段空闲内存分配给这个新对象。
压缩:从堆空间的头部开始,将存活的对象拷贝放在一段连续的内存空间中,那么其余的空间就是连续的空闲空间。
复制:将堆空间分成两部分,只在其中一部分创建对象,当这个部分空间用完的时候,将标记过的可用对象复制到另一个空间中。
常用垃圾回收器算法:
串行回收器:每次垃圾回收会启用一个线程同时暂停其他线程。如果回收时间长,对应用会有较大影响。
并行回收器:垃圾回收时启用多个线程,并行处理。在处理的过程中也会暂停应用线程。
并行回收器CMS:在初始化标记时暂停应用线程,之后与应用并行执行,直到在垃圾回收之前,再次暂定线性进行重标记,在最终执行垃圾回收时与应用程序并行执行。减少了应用程序的影响。
G1回收器:与CMS类似,只是每个阶段都是多线程的方式执行。
二、设计一个秒杀系统,主要的挑战和问题有哪些?核心的架构方案或者思路有哪些?
主要的挑战
1、使除固定数量的人可以进入支付页外,其他的请求全部通过静态页面消化掉。
2、安全,防止通过查看url,通过url直接进入支付页。
3、防止超卖。
核心架构方案
1、页面静态化,在秒杀未开始前,尽量不跟应用服务器进行交互。将商品列表页面做一个大图,减少获取图片时TCP连接的个数,和与静态服务器的交互次数。
2、安全。防止刷单,秒杀未开始前进入支付页的请求直接返回错误。还有就是课程中说的方法,前端用一个js文件保存秒杀使用的商品id,在秒杀未开始前js内容为空,通过这个js进行判断。
3、使用redis的Hash数据结构保存秒杀商品的销量。
评论