写点什么

JVM 垃圾回收原理和秒杀设计

发布于: 2020 年 08 月 05 日
JVM垃圾回收原理和秒杀设计

JVM 垃圾回收原理

what

垃圾回收(Garbage Collection)是 Java 虚拟机(JVM)垃圾回收器提供的一种用于在空闲时间不定时回收无任何对象引用的对象占据的内存空间的一种机制。

why

在 Java 中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。 垃圾回收能自动释放内存空间,减轻系统的负担,垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存。

when

虚拟机在以下三种情况会进行垃圾回收

  1. 会在 cpu 空闲的时候自动进行回收  

  2. 在堆内存存储满了之后  

  3. 主动调用 System.gc()后尝试进行回收


where

垃圾回收发生在堆中,一般会将堆分为以下几个区域。

jdk1.7 版本和之前版本是


jdk1.8 开始移除了永久


GC 有两种:Minor GC 和 Full GC

  • 次数上频繁收集 Yong 区 Minor GC

  • 次数上较少收集 Old 区 Full GC

  • 基本不动 Perm 区


新生代 GC(Minor GC)

新生代 GC 指发生新生代的的垃圾收集动作,Minor GC 非常频繁,回收速度一般也比较快。

老年代 GC(Major GC/Full GC)

老年代 GC 指发生在老年代的 GC,出现了 Major GC 经常会伴随至少一次的 Minor GC(并非绝对),Major GC 的速度一般会比 Minor GC 的慢 10 倍以上。


how

垃圾回收器判断对象已死亡之后会通过相应的垃圾回收算法进行垃圾回收。


判断对象死亡

引用计数法

给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的。这个方法实现简单,效率高,但是目前主流的虚拟机中并没有选择这个算法来管理内存,其最主要的原因是它很难解决对象之间相互循环引用的问题。

可达性分析算法

从 GC Roots 开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的。


垃圾回收器

  • Serial 收集器:单线程的垃圾回收器,新生代采用复制算法,老年代采用标记-整理算法。

  • ParNew 收集器:是 Serial 收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为和 Serial 收集器完全一样。

  • Parallel Scavenge 收集器:类似于 ParNew 收集器,Parallel Scavenge 收集器提供了很多参数供用户找到最合适的停顿时间或最大吞吐量.

  • Serial Old 收集器:Serial 收集器的老年代版本

  • Parallel Old 收集器:Parallel Scavenge 收集器的老年代版本

  • CMS 收集器:CMS 收集器是一种以获取最短回收停顿时间为目标的收集器

  • G1 收集器:G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足 GC 停顿时间要求的同时,还具备高吞吐量性能特征


垃圾回收算法

标记-清除算法

算法分为“标记”和“清除”阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。它是最基础的收集算法,效率也很高,但是标记清除后会产生大量不连续的碎片

复制算法

将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把使用的空间一次清理掉。

标记-整理算法

标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收,而是让所有存活的对象向一段移动,然后直接清理掉端边界以外的内存

分代收集算法

根据对象存活周期的不同将内存分为几块,在每块内存采用不同的算法进行内存回收。例如新生代选择复制算法,老年代选择“标记-清楚”或“标记-整理”算法


如何设计一个秒杀系统

面临的问题

  • 高并发,秒杀面临的是瞬时极高的并发请求情况

  • 大流量,秒杀一般都是会持续一段时间,在这段时间内使系统承受特别高的请求流程

  • 库存问题,秒杀往往都是一比一万甚至一比一千万的库存请求比,因此防止多卖是一个很关键的要点

  • 防刷,秒杀活动一定会引来众多的非法请求或者自动批量请求,因此对这些不正常的请求的拦截处理也是很关键的


设计思路

  1. 请求拦截,降低下游压力。前端页面动静分离,通过 CDN 减少到服务器的请求;通过限流措施限制直接到服务器的请求;通过动态 URL 防止恶意批量请求。

  2. 善用缓存提高系统性能。善用缓存主要是针对库存的,库存可以放到 Reids 缓存中,来提高扣减库存吞吐能力。对于热点商品的库存可以利用 Redis 分片存储。

  3. 善用消息队列,对请求进行消峰。对于秒杀系统瞬时会有大量用户涌入,所以在抢购一开始会有很高的瞬间峰值。高峰值流量是压垮系统很重要的原因,实现削峰的常用的方法有利用缓存和消息中间件等技术。


PLAN B

为了以防万一,一定要有 planB 来兜底,主要就是四个方向:限流、降级、熔断和隔离。流量超过预警值就需要限流了,如果限流没解决,那么久需要降级,如果降级还是扛不住,就需要熔断保全其它系统,熔断的同时还需要进行隔离,不再调用其它系统引起连锁反应。


发布于: 2020 年 08 月 05 日阅读数: 56
用户头像

还未添加个人签名 2018.04.29 加入

还未添加个人简介

评论

发布
暂无评论
JVM垃圾回收原理和秒杀设计