在上一章,我们了解Java虚拟机的分布以及各个部分的主要存储内容,下面将介绍GC的长用回收算法。
1.引用计数法:
引用计数法是比较古老的一种垃圾回收算法。主要实现就是当任何一个对象引用A对象的时候,则在A对象的计数器上加1,如果引用失效的时候,则将A的计数器减1,如果对象A的引用计数器为0,则回收该对象的内存空间。这种方式虽然简单,但是存在不足,就是当A对象引用B对象,B对象又引用A对象,这样,A与B对象的计数器一直都是1,产生死锁,引起内存泄漏。
2.标记-清除法
在Java堆内存中从根节点开始遍历整个堆,标记所有可到达的对象。因此没有被标记的对象则被回收,在不连续的内存空间这样会产生大量的内存碎片。
3.复制算法
将内存划分为两个区域,每次只使用一个区域,当进行垃圾回收的时候,将正在使用的对象复制到另一块没有被使用的区域,然后清楚之前正在使用的区域所有对象,这样做的的好处是不存在内存碎片,但是需要2倍的内存空间,所有适用于新生代的回收。在新生代分为eden空间,survivor空间也叫from空间和to空间,在垃圾回收时,eden空间的存活对象会被复制到未使用的survivor空间(这里假设是to),而正在使用的survivor空间中仍然存活的对象将挪至年老代,然后eden剩下的对象将全部清楚。
4.标记-压缩算法
该算法在标记清除法上,做了一定优化,就是一样是从根节点开始遍历,找到所有可遍历到达的对象进行标记,不同的是将未标记的对象压缩到内存的一端,这样在进行回收的时候,就避免了不连续的内存空间造成的内存碎片。这种算法用于年老代的回收。
总而言之,没有一种算法能完全取代另一种算法,基本上在不同区域结合不同的算法,这样才能高效的实现垃圾回收。
版权声明:本文为博主原创文章,未经博主允许不得转载。