写点什么

第 9 周作业 1

用户头像
Yangjing
关注
发布于: 2020 年 11 月 22 日

请简述 JVM 垃圾回收原理

JVM 垃圾回收就是将 JVM 堆中已经不在使用的对象清理掉,释放宝贵的内存资源。

JVM 通过使用可达性分析算法进行垃圾对象的识别。具体的步骤如下:

  • 从线程栈帧中的局部变量,或者方法区的静态变量出发,将这些变量引用的对象进行标记

  • 然后看这些被标记的对象是否引用了其他对象,继续进行标记

  • 最终所有被标记过的对象都是被使用的对象,而那些没有被标记的对象就是可进行回收的垃圾对象了。


垃圾识别出来后,通过下面 3 种方法进行内存的回收:

  • 清理:将垃圾对象占据的内存清理掉。实际是在一个空间列表中,将垃圾对象占用的内存空间标记为空闲,当应用程序需要内存空间时,就从空闲列表找一段空闲内存分配给程序

缺点:清理过程效率低、产生了内存碎片,提高了垃圾回收频率

  • 压缩:清理会带来空闲内存的不连续,无法得到大的可用空闲内存,这时候可以通过压缩,从堆空间的头部开始,将存活的对象拷贝放到一段连续的内存空间中,那么其余的空间就是连续的空闲空间了。

缺点:对象移动,效率不高

  • 复制:将堆空间分成两部分,只在其中一部分创建对象,当这个部分空间用完的时候,将标记为非垃圾的对象复制到另一个空间,原来的空间就全部恢复为空闲内存空间。复制算法相比压缩算法效率更高,不用考虑内存碎片,每次需要复制的也只是需要使用的对象。

缺点:可用内存大小缩小为原来的一半,对象存活率高的时候会频繁的复制


JVM 将内存空间分为 2 部分,新生代、老年代。不同代使用不同的垃圾回收算法。

可以分为两个区域的原因是:大部分新生对象很快无用,存活较长时间的对象,可能存活更长时间

新生代: 新生代的的堆空间划分为了 Eden 区、 Survivor From 区(S0)、Survivor To 区(S1),三者默认是 8:1:1,每次只在 Eden 区为对象分配内存,当 Eden 区内存不足时,触发 YGC,标记使用中的对象,被一次性复制到 S0 区,Eden 区 恢复成全部为空闲内存。当触发下一次 YGC 时,会将 Eden 和 S0 区的存活对象移动到 S1 区,同时清空 Eden 和 S0 区。当再次出发 YGC 时,处理的区域变成了 Eden 和 S1 区(即 S0 和 S1 进行角色互换)。每进行一次 YGC,存活对象的年龄+1,当达到阈值时,会晋升到老年代。

老年代:标记出存活对象后,移动存活对象到一段连续的内存空间,解决内存碎片问题。


垃圾回收器

都存在 stop the word,减少响应时间的方法在于减少 stop the word 的时间,通过将垃圾回收过程拆分更细,有些阶段就不需要 stop the word。

  • 串行回收器

  • 并行回收器

  • 并发回收器 CMS

  • G1

Java 8 或之前 都是 并行 GC;后面都是 G1


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

秒杀业务通常是有限的商品,在极低的价格在限定时间销售。

主要的挑战和问题有:

  1. 秒杀时间的网络流量带宽突然的暴增。

  2. 请求数多,消耗服务器资源,增加服务器负载。

  3. 并发数高,通常是一个时间点大量的用户同时操作。应用中无法处理业务逻辑。

  4. 数据库的查询、修改存在瓶颈。


解决方案和思路

  1. 页面静态化,不生成动态内容,降低服务器负载。

  2. 静态资源和文件走 CDN,不让大多数请求流量到服务器。

  3. 分布式缓存并发控制,只放一部分请求进入秒杀业务逻辑。

  4. 简化秒杀流程,降低应用的查询和操作,防止崩溃。

  5. 次要逻辑异步化,对秒杀流量削峰。

  6. 秒杀业务与其他业务分离,减少相互影响。

  7. 秒杀地址和参数开始前隐藏,随机地址,预发秒杀器。


发布于: 2020 年 11 月 22 日阅读数: 26
用户头像

Yangjing

关注

还未添加个人签名 2017.11.09 加入

还未添加个人简介

评论

发布
暂无评论
第9周作业1