第 9 周作业 1
请简述 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
设计一个秒杀系统,主要的挑战和问题有哪些?核心的架构方案或者思路有哪些?
秒杀业务通常是有限的商品,在极低的价格在限定时间销售。
主要的挑战和问题有:
秒杀时间的网络流量带宽突然的暴增。
请求数多,消耗服务器资源,增加服务器负载。
并发数高,通常是一个时间点大量的用户同时操作。应用中无法处理业务逻辑。
数据库的查询、修改存在瓶颈。
解决方案和思路
页面静态化,不生成动态内容,降低服务器负载。
静态资源和文件走 CDN,不让大多数请求流量到服务器。
分布式缓存并发控制,只放一部分请求进入秒杀业务逻辑。
简化秒杀流程,降低应用的查询和操作,防止崩溃。
次要逻辑异步化,对秒杀流量削峰。
秒杀业务与其他业务分离,减少相互影响。
秒杀地址和参数开始前隐藏,随机地址,预发秒杀器。
版权声明: 本文为 InfoQ 作者【Yangjing】的原创文章。
原文链接:【http://xie.infoq.cn/article/714c3ac278331b5eada7af8a6】。文章转载请联系作者。
评论