JVM理解二 垃圾回收机制

概述

垃圾回收机制是java程序运行过程中,对结束的方法或则线程运行的内存进行回收。讲到垃圾回收就要考虑垃圾回收的原理即垃圾回收算法,也要考虑垃圾回收的工具即垃圾回收器。

垃圾回收算法

1.引用计数算法(引用计数式垃圾回收)

引用计数算法就是给对象添加一个引用计数器,每当一个地方引用一次将计数器的值加一;当引用失效时计数器就减一。原则上当引用计数器的值为0的对象是不可能再被使用,也就是说当引用计数器的值不为0的对象是不会被回收的。But(只要一说原则肯定会加but)如果对象A和对象B只是相互引用,其他对象没有再引用他们。他们的引用次数都不为零,这时java 虚拟机就不会回收他们吗? NO,java虚拟机一样会回收他们,所以可以判断出java虚拟机不是通过引用计数算法来判断对象是否存活。

2.可达性分析算法(GC ROOTS 追踪式垃圾回收)

当前主流的语言基本上都是通过可达性算法来判断对象是否存活的。该算法的思路:从root节点开始找一条引用链,凡是能在引用链上的对象,说明都在使用中。引用链达不到的对象,证明对象没有被使用,就要可以回收这些没有被使用的对象。
参考文档

Obj A
Obj B
Obj C

对象A,B,C相互引用

GC Root
Obj D
Obj E
Obj F
Obj G

根据GC root算法能在root引用链上的是正在使用即D\E\F\G这个四个对象是正在使用中不能回收,A\B\C对象没有在root引用链上所以要被回收掉。

3.追踪式垃圾回收-分代收集理论算法

当前的商用虚拟机大多数都遵循了“分代收集”。收集器将java堆分为了不同的区域,将回收对象按照年龄分配到不同的区域之中存储。一般的java堆分为年轻代(Young Generation)和老年代(old Generation)。当年轻代经过一次垃圾回收时存活下来的少量对象,会逐步晋升为老年代。但是分代理论也存在了一定的困难,那就是有可能在老年的对象引用了年轻代的对象,这样就出现了一个现象叫做 跨代引用。
对于跨代引用,当GC扫描年轻代时发现了,有年轻代引用了老年代,为了判断可达性是不是要扫描一下老年代区看看是否可达,这样就浪费了很多资源。针对这中情况就出现了一个全局的数据结构“记忆集”,这个结构将老年代划分了若干个小块,标识出了老年代哪一块存在跨代引用。这样当存在跨代引用时,只需要扫描记忆集中的东西就行了,不用扫描整个老年代。
分代收集常用的定义:
新生代收集(Minor GC/YangGC) 目标只收集新生代的垃圾收集
老年代收集(MajorGC/old GC)目标只收集老年代的垃圾收集
整堆收集(Full GC)收集整个java堆和方法区的垃圾收集

4.标记-清除算法

标记清除算法:是标记出需要回收的对象,标记完成后统一回收掉所有标记的对象,也可以反过来。标记存活的对象,没有标记的对象回收掉。标记对象的过程就是用来扫描是否属于垃圾的判定过程。标记清除算法有两大缺点:(1)在标记和清除过程中,内存会出现大量不连续的碎片,内存空间碎片太多会导致当创建较大的对象时,找不到一块足够连续内存而不得不提前触发另一次垃圾收集动作;(2)执行效率不稳定,java堆中存在很多对象,这样就存在了很多标记和清除,这样就导致了随着对象的增多,垃圾回收效率降低。
在这里插入图片描述

5.标记-复制算法

标记复制算法在1969年叫做“半区复制”,也就是当虚拟机运行时,将内存分为两半。一半留着不用,一半使用标记算法,将存活的对象标记出来,然后复制到另一半,再将原来的一半进行清除掉。这样就是不会出先内存碎片,因为将存活的对象复制到另一半只移动堆顶指针,按顺序排放。但是这样就存在了大量的内存复制,而且代价就是将可已使用的内存缩小一半。最新的一代内存分布,将java堆很为了把新生代分为了一块较大的Eden空间和2块较小的Survivor空间,每次分配使只使用了一块Survivor和Eden。在垃圾回收时,将survivor和eden的区域依然存活的对象一次性复制到另外一块survivor中,然后一次行清理掉用过的survivor和eden。eden和survivor的比例的默认比例是 8:1.
在这里插入图片描述

6.标记-整理算法

标记整理算法和标记复制算法类似,标记复制是将对象被动的复制到区域中,是非移动式回收算法。标记整理是将移动式回收算法,就是将存活的对象标记,然后对未存活的对象进行清除。清除后,已经存活下来的对象向内存空间一端移动,然后直接清除掉边界以外的内存。
但是这样移动式的回收对象是有一定弊端的:就是在进行移动式回收对象时,必须要将用户的应用程序停止,才能进行。这样使的使用者不得不小心的权衡这个利弊。在很多的垃圾回收器中就是利用这个将用户程序停止时间,来进行优化垃圾回收算法。这是移动式回收垃圾时的弊端。非移动式回收 会造成空间碎片化,如标记-清除算法这只能以来复杂的内存分配器和访问器来解决,但是内存分配时会干扰用户访问内存的操作,这样会影响用户访问程序的吞吐量。 非移动式对象停顿时间会比较短,甚至不需要停顿,是延迟性比较低的算法。

7.常见的垃圾回收器

在这里插入图片描述
Serial、ParNew、Paraller Scaveng 是新生代回收器,CMS、Serial Old,Parallel Old 是针对老年代的垃圾回收器。G1综合性的。目前用的最广泛的是
CMS+ParNew 回收器:
CMS 是以获取最短回收停顿时间为目标的回收器,是基于标记清除算法来实现的。
流程有初始标记-并发标记-重新标记-并发清除。
G1 回收器:G1从整体上看是用了标记-整理的算法,但是看局部是标记-复制实现。G1是CMS的继承和优化,终将取代CMS。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值