JVM垃圾收集器(重点知识)

判断对象是否存活?

引用计数算法(有引用计数器+1,引用失效计数器-1;当计数器的值为0的时候,那么该对象就是可被GC回收的垃圾对象)

可达性分析算法(当一个对象没有任何引用链相连时,那么该对象就是可被GC回收的垃圾对)

Java 中的四种引用类型

强引用:最普遍、如果一个对象具有强引用,垃圾回收器绝对不会回收他。如果强引用对象不使用时,需要弱化从而使GC能够回收。

软引用:如果一个对象只具有软引用,则内存空间充足时,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。

弱引用:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域我的过程,一旦发现了只具弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

虚引用:主要用来跟踪对象被垃圾回收的活动,可以在垃圾收集时收到一个系统通知。

垃圾收集算法:

分代收集理论

分代存储:兼顾垃圾收集的时间开销和内存空间的有效利用
分代收集:

堆区按照分代存储的好处:在Java堆区划分成不同区域后,垃圾收集器才可以针对不同的区域,安排与该区域存储对象存亡特征相匹配的垃圾收集算法:标记-复制算法、标记-清除算法、标记-整理算法等。

垃圾收集类型划分:

  • 部分收集(Partial GC):没有完整收集整个Java堆的垃圾收集,其中又分为:
    • 新生代收集(Minor GC / Young GC)
    • 老年代收集(Major GC / Old GC)
    • 混合收集(Mixed GC):收集整个新生代和部分老年代的垃圾收集。
  • 整堆收集(Full GC):收集整个Java堆的垃圾收集。

垃圾收集算法

标记-清除算法 ( Mark-Sweep )

第一步:利用可达性去遍历内存,把存活对象和垃圾对象进行标记; 第二步:在遍历一遍,将所有标记的对象回收掉; 特点:效率不行,标记和清除的效率都不高;标记和清除后会产生大量的不连续的空间分片,可能会导致之后程序运行的时候需分配大对象而找不到连续分片而不得不触发一次GC;

标记-复制算法 ( Copying )

将内存按照容量大小分为大小相等的两块,每次只使用一块,当一块使用完了,就将还存活的对象移到另一块上,然后在把使用过的内存空间移除; 特点:不会产生空间碎片;内存使用率极低;

标记-整理算法 ( Mark-Compact )

第一步:利用可达性去遍历内存,把存活对象和垃圾对象进行标记; 第二步:将所有的存活的对象向一段移动,将端边界以外的对象都回收掉; 特点:适用于存活对象多,垃圾少的情况;需要整理的过程,无空间碎片产生;

当前虚拟机的垃圾收集都基于分代收集思想,根据对象存活周期的不同,将内存分为几个不同的区域,在不同的区域使用不同的垃圾收集算法。

垃圾收集器

Serial 收集器(新生代)

串行,采用“标记-复制”算法,单线程收集器,好处:简单高效

Serial Old 收集器(老年代)

单线程收集器,“标记-整理”算法。在JDK5及以前版本,与Parallel Scavenge收集器搭配使用;作为CMS收集器发生失败时的后备预案;

ParNew 收集器(新生代)

多线程垃圾收集器,与Serial Old、CMS搭配使用,“标记-复制”算法。

Parallel Scavenge 收集器(新生代)

多线程垃圾收集器,“标记-复制”算法,目标:达到一个可控制的吞吐量(处理器用于运行用户代码的时间与处理器总消耗时间的比值)

Parallel Old 收集器(老年代)

多线程收集器,“标记-整理”算法。在注重吞吐量或者处理器资源较为稀缺的应用场景,都可以优先考虑 Parallel Scavenge 收集器 + Parallel Old 收集器这个收集器组合。

CMS 收集器(老年代)

CMS:是一种以获得最短回收停顿时间为目标的收集器,标记清除算法,运作过程:初始标记,并发标记,重新标记,并发清除,收集结束会产生大量空间碎片;

是一种以获取最短回收停顿时间为目标的收集器,“标记-清除”算法,它第一次实现了让垃圾收集线程与用户线程(基本)同时工作。这类应用通常都会较为关注服务的响应速度,希望系统停顿时间尽可能短,以给用户带来自好的交互体验。

工作流程

初始标记:标记GC Roots 能直接关联到的对象,速度很快

并发标记:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长,但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行;

重新标记:这个阶段的停顿时间一般会比初始标记阶段的时间长,远远比并发标记阶段时间短

并发清除:理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的

优点:并发收集、低停顿

缺点:影响用户线程的执行效率。无法处理浮动垃圾、产生大量空间碎片

G1 收集器(老年代)

标记整理算法实现,运作流程主要包括以下:初始标记,并发标记,最终标记,筛选回收。不会产生空间碎片,可以精确地控制停顿;G1将整个堆分为大小相等的多个Region(区域),G1跟踪每个区域的垃圾大小,在后台维护一个优先级列表,每次根据允许的收集时间,优先回收价值最大的区域,已达到在有限时间内获取尽可能高的回收效率;

划分2048个大小相同的独立区域,取值范围1-32,2的N次幂

初始标记(Initial Marking):这个阶段仅仅只是标记GC Roots能直接关联到的对象,这阶段需要停顿线程,但是耗时很短。

并发标记(Concurrent Marking):从GC Roots开始对堆的对象进行可达性分析,递归扫描整个堆里的对象图,找出存活的对象,这阶段耗时较长,但是可以与用户程序并发执行。

最终标记(Final Marking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后遗留记录。

筛选回收(Live Data Counting and Evacuation):负责更新 Region 的统计数据,对各个 Region 的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划。可以自由选择多个Region来构成会收集,然后把回收的那一部分Region中的存活对象==>复制==>到空的Region中,最后对那些Region进行清空。

特点:并行与并发、分代收集、空间整合(G1从整体看是基于“标记-整理”,从局部上是基于“标记-复制”,G1运行期不会产生内存空间碎片,收集后能提供规整的可存内存)、用户指定期待停顿。

G1 垃圾收集器与CMS垃圾收集器的区别

算法不同:CMS采用“标记-清除”容易产生内存碎片,执行若干次GC后进行1次碎片整理。G1从整体来看是基于“标记-整理”算法实现的收集器,从局部(两个Region之间)上来看是基于“标记-复制”算法实现。意味着G1垃圾收集器不会产生内存空间碎片,垃圾收集完成后,能提供规整的可用内存,不会导致因为大对象分配内存时无法找到连续内存空间而提前触发垃圾收集。

场景不同:小内存应用上CMS的表现大概率优于G1,而大内存应用中,G1则能发挥优势。大小内存的参考值分水岭大概在6GB-8GB.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值