JVM学习之垃圾收集(9)

一 垃圾收集算法及垃圾收集器

1 引用计数法(引用计数收集器)

(1)引用应该是指对象的指针,要区别变量(局部变量,类变量,或者实例变量),但习惯上变量也被当作引用了

(2)当对象的引用被分配给一个变量,这个对象的引用计数被置为1

(3)当任何其他变量被赋值为对这个对象的引用时,计数加1

(4)当一个对象的引用超过了生存期或者被设置一个新值时,引用计数减1

(5)任何引用计数为0的对象可以被当作垃圾收集,当一个对象被垃圾收集的时候,它引用的任何对象计数值减1

 

        引用计数法的好处是执行效率高,缺点是无法检测出循环,所以这种技术现在已经不为人所接受,现实中所遇到的jvm大多是使用自追踪算法

 

2 追踪算法(标记并清除,跟踪收集器)

        跟踪收集器追踪从根结点开始的对象引用图,在追踪过程中遇到的对象以某种方式打上标记,要么在对象本身设置标记,要么用一个独立的位图来设置标记,当追踪结束时,未被标记的对象就知道是无法触及的,从而可以被收集

 

3 压缩收集器和拷贝收集器

        标记并清除收集器通常使用 的两种策略是压缩和拷贝.这两种方法都是快速地移动对象来减少堆碎块.

        压缩收集器把活动的对象越过空闲区滑动到堆的一端,使堆的另一端出现一个大的连续空闲区,所有被移动的对象的引用也被更新,指向新的位置(但通常是让引用指向句柄表里的句柄,对象移动后改变句柄即可,不用修改所有对象的引用)

        拷贝垃圾收集器使用的算法一般被称为"停止并拷贝",堆被分为两个区,任何时候都只使用其中的一个区域,直到这个区域耗尽,程序执行暂时中止,堆被遍历,把活动对象拷贝到另外一个区域,并把原来区域里的垃圾对象清除,如此反复.

 

4 按代收集的收集器

        把堆划分成两个或更多的子堆,每一个子堆为一代,最年幼的那一代进行最频繁的垃圾收集,每当对象在它所属的代中变得成熟,即逃过了多次垃圾收集,它们就被转移到更高的代中去.按代进行的收集技术可以应用于拷贝算法,也可应用于标记并清除算法

 

5 自适应收集器

        自适应算法会监视堆中的情形,对应地高速为合适的垃圾收集技术

 

6 火车算法

(1)属于渐近式垃圾收集算法,属于按代收集方式.每次只对某一个区域进行垃圾收集,减少垃圾收集时程序运行停顿时间过长的问题

(2)火车算法的目的是为了在成熟对象空间(最高代)提供限定时间的渐进收集

(3)通过检查对象在火车或车厢间的引用关系,执行必要的对象拷备.每一次火车算法被执行时,它要么收集最小数字火车的最小数字车厢,要么收集整列最小数字火车

 

 

二 对象的终结

 

1 垃圾收集器清除对象前发现不再被引用的对象存在finalize()方法后,要先执行所有的终结方法,然后,垃圾收集要器必须从根结点开始再次检测不再被引用的对象(第二遍扫描),这个步骤是必要的,因为终结方法可能"复活"了某些不再被引用的对象.

 

关于复活的例子

 

例如在对象A着保存着对象B的引用b1,对象B还被另一个不在A的引用b2保存,并且没有没有引用指向A了,那么垃圾收集前执行A的finalize()方法,如果有: b1.a = this ,即A把自己的引用附给了B的属性a,那么A复活了.

 

2 当然,为了减少释放内存的时间,在扫描到某些对象拥有终结方法和运行这些终结方法之间,垃圾收集器可以有选择地插入一个步骤,一旦执行了第一遍扫描,它可以运行一次小型的追踪,即从需要执行终结的对象开始,而非从根结点开始.任何满足如下两个条件的对象,可以立即被释放,因为这些对象不可能在执行终结方法时复活

 

(1)从根结点开始不可触及(从第一遍扫描中检测出)

 

(2)从将要被终结的对象开始不可触及

 

 

三 引用对象

 

1 引用对象有三种类型(注意引用对象,可触及对象,引用队列的区别与联系):

(1)SoftReference:在SoftReference对象强可触及的情况下,假如一个对象的引用只被SoftReference对象拥有,那么这个对象是软可触及的,因为垃圾收集器从根节点开始只有通过一个软引用才能触及到此对象.对象可以从根节点开始通过一个或多个未被清除的软引用对象触及,当垃圾收集器回收了软可触及对象所占据的内存,它会清除所有到此软可触及对象的软引用.当垃圾收集器清除一个和引用队列有关联的软引用对象时,它把该软引用对象加入队列

(2)WeakReference:分析同上

(3)PhantomReference:分析同上

 

引用对象的目的是为了能够指向某些对象,这些对象仍然随时可以被垃圾收集器收集.

 

2 在创建引用对象时把对象引用和java.lang.ref.ReferenceQueue类的实例构造方法的参数,当垃圾收集器对引用目标的可触及性状态做了改变时,它就会把引用对象加入到与它有关联的引用队列中去.垃圾收集器执行它的enqueue()方法,这个方法是在超类的Reference中定义的,只有在创建引用对象时关联了一个队列,并且仅当该对象的enqueue()方法第一次执行时,才把引用对象加入到这个队列中.程序可以有两种方法来监控引用队列: poll()(不阻塞)和remove()(阻塞)

 

3 对象的可触及性:

(1) 可触及(强可触及): 从根节点开始的任何直接引用,是强可触及的,同理,任何从强可触及对象的实例变量引用的对象也是强可触及的.

 

(2) 可复活

(3) 不可触及: 不可达且不可能被finalize()复活,即执行第二遍扫描还是不可触及

(4) 软可触及

(5) 弱可触及

 

(6) 影子可触及: 对象不是强可触及,软可触及,也不是弱可触及,并已经被断定不会被任何终结方法复活(如果它自己定义了终结方法,它的终结方法已经被运行过了),并且它可以从根节点开始通过一个或多个未被清除的蚊子引用对象触及,一旦某个被影子引用的对象变成影子可触及状态,垃圾收集器产即把该引用对象加入队列,垃圾收集器从不会清除一个影子引用,所有的影子引用都必须由程序明确地清除

 

三种引用对象区别■■■: 

(1)含义区别:

        垃圾收集器把软引用或弱引用对象加入引用队列意味着它的引用对象刚刚离开软可触及状态(★这里仅是指对象被垃圾收集器回收),但是垃圾收集器把影子引用对象加入队列标志着引用目标已经进入了影子可触及状态,影子可触及对象会保持影子可触及状态,★直到程序显式地清除了引用对象.

 

(2)作用区别:

        虚拟机实现一般会在抛出OutOfMemoryError之前清除软引用,并且是先清除老的而不是新的,这取决于实现;

 

        弱引用类似于软引用,不同的是,它必须在判断出对象处于弱连接状态时就★立即清除弱引用,如下面的WeakHashMap:

 

        如果把一个键值对加入到WeakHashMap,会一直保留在WeakHashMap里面,直到在程序显式地使用remove()方法移出它,或者垃圾收集器发现关键字对象是弱可触及的(即没有其他强引用引用这个关键字对象).

    

        垃圾回收期并不会总在第一次就找到弱引用,而是会找几次才能找到,所以说弱引用所指的对象被回收具有很强的不确定性,与软引用相比,弱引用所指对象被回收的可能性大,也就是说,只要一个对象处于弱可及状态,那么就有可能被回收,而软可及对象一般是内存不够才会被回收

 

    影子引用(虚引用)对象没有一个关联的引用队列会无法创建实例;影子引用无法获得对影子可触及对象的强引用,get()方法总是返回null,

    ★软引用和弱引用可以单独使用,虚引用不能单独使用,虚引用的作用是就跟踪对象被垃圾回收的状态,程序可以通过检测与虚引用关联的虚引用队列是否已经包含了指定的虚引用,从而了解虚引用的对象是否即将被回收。

    ★所以说,利用影子引用是没有办法操作被引用对象本身的,只能做一些与被引用对象相关的,但是又不需要被引用对象参与的善后处理动作。因此,影子引用更像是一个java虚拟机对外暴露的终结对象前的回调标记接口。通过这个接口,你可以在一个对象被销毁之前得到通知,然后做一些处理。这可能是Sun因为考虑到java虚拟机的垃圾回收机制不受程序员控制的关系而衍生出来的一种这种方案。

 

4 三种引用对象的概括:

(1) SoftReference: 当目标对象变为软可及时(标记清楚法判定)并且内存不充足时,垃圾收集器可能回收目标对象

(2) WeakReference: 当目标对象变为弱可及时(标记清楚法判定)并且垃圾收集器发现弱可及的目标对象时,垃圾收集器就可以回收目标对象

 

(3) PhantomReference: 当目标对象不是其他可触及状态,并且不可复活时(finally方法已执行过了), PhantomReference对象被加入引用队列,表示目标对象只能等待着被垃圾收集器回收.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值