垃圾回收算法简介

自动垃圾回收(GC)是java与c++语言最重要的区别之一。

在java中,垃圾回收线程是一个优先级很低的线程,一般在内存不够或者没有其他线程运行的时候虚拟机才会运行垃圾回收线程来进行垃圾回收。

垃圾收集器不可以被强制执行,但程序员可以通过调用System.gc()或者Runtime.getRuntime().gc()来建议jvm安排gc运行(注意其实这两个方法本质是一样的,前者的实现里就是调用的后者)。一般不建议使用System.gc(),因为这个命令只是建议jvm进行垃圾回收,具体是否执行垃圾回收和什么时候回收都是jvm控制的。

垃圾回收算法大致可以分为两类,一类是古老的引用计数收集器,另一类就是跟踪收集器。


引用计数收集器

引用计数是垃圾收集器中的早期策略。在这种方法中,堆中的每个对象都有一个自己的引用计数器。当该对象每被引用一次,引用计数器就加1,当对象失去一个引用时,计数器就减1。当引用计数为0时,对象就可以被当做垃圾进行回收。引用计数收集器的缺点是需要对引用计数器进行维护,增大了程序执行的开销。

跟踪收集

早期的jvm使用引用计数,现在大多数jvm采用对象引用遍历。跟踪收集器引入了根集的概念。从根节点开始,遍历根节点的所有引用。所谓的根节点,包括以下几种:

  • 方法区中的静态属性(静态属性指向一个对象)
  • 方法区的中的常量(常量指向一个对象)
  • 虚拟机栈中的局部变量(变量指向一个对象)
  • 本地方法栈中JNI(native修饰的方法指向的对象)

标记清除法

从根节点开始,遍历根节点的所有引用,以此判断对象是否可达,对可达的对象做一个标记。这样遍历完之后,没有被标记的对象可以被认为是垃圾对象从而进行垃圾回收。

标记压缩法(Compacting Collector)

标记清除法会带来大量内存碎片,为了解决这个问题,引入了标记压缩法。标记压缩法在标记清除法的基础上,将存活的对象移动到堆的另一端,并更新相应对象的引用。然后将存活对象空间之外的垃圾对象全部回收。在基于标记压缩算法的收集器的实现中,一般增加了句柄和句柄表。

复制法(Coping Collector)

该方法是为了克服句柄的开销和解决堆碎片从而提出的垃圾回收方法。它开始时把堆分成一个对象区和多个空闲区,程序从对象区为对象分配空间,当对象满了,基于coping算法的垃圾回收就从根集中扫描活动对象,并将每个活动对象复制到空闲区(使得活动对象所占的内存之间没有空闲间隔),这样空闲区变成了对象区,原来的对象区变成了空闲区,程序会在新的对象区中分配内存。在对象区与空闲区进行切换的过程中,程序暂停执行。

分代法(Generational Collector)

分代收集算法是目前大部分JVM的垃圾收集器采用的算法。

复制方法的缺陷是对每一个存活的对象都需要进行复制,这增加了程序等待的时间。而对象可以分为新生代对象和老生代对象。前者指生存时间较短的对象,后者指生存时间较长的对象,一般经历过多轮垃圾回收,新生代和老生代放在不同的域中。由于老生代对象生存时间较长,如果每次都对老生代对象进行复制,会消耗大量的时间,带来很大的系统开销。所以分代法对老生代对象采用标记压缩法,而对新生代对象采用复制法,以此优化性能。

在复制算法中,HotSpot把年轻代分为了三个部分,一个Eden区和两个Survivor区(分别叫from和to),默认比例为8:1:1。

在GC开始时,对象只存在于Eden区和名为“From”的survivor区。GC的时候,Eden区所有对象都被复制到Survivor的“To”区,并且年龄加1,而“From”区中的对象根据年龄值决定去向,达到一定年龄值(可以通过-XX:MaxTenuringThreshold设置)的对象被移动到年老代中,没有达到的则被复制到“To”区中。经过这次GC后,Eden和from区被清空,然后from区和to区交换角色。当To区被填满之后,会将其中的所有对象都移动到老年代中。

finalize()方法

在JVM垃圾回收器收集一个对象之前,一般要求程序调用适当的方法释放资源(这里的资源一般指非内存资源,如io流,数据库连接等),但在没有明确释放资源的情况下,Java提供了缺省机制来终止该对象心释放资源,这个方法就是finalize()。它的原型为:protected void finalize() throws Throwable。在finalize()方法返回之后,垃圾收集开始执行。原型中的throws Throwable表示它可以抛出任何类型的异常。

垃圾收集器可参考另一篇文章-JVM内存模型与性能调优

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值