Java引用类型

来源:互联网 发布:淘宝上二手手机良心店 编辑:程序博客网 时间:2024/06/05 13:22

1. 强引用(Strong Reference)
     强引用是Java的默认引用实现,例如:Object  object = new Object(),这里的object就是强引用。
     如果一个对象具有强引用,它会很长时间的存货在JVM中。当内存空间不足时,JVM宁愿抛出OutOfMemory错误使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。当然,只有当没有任何对象指向它是GC执行后才会将它回收。

2. 软引用(Soft Reference)
     如果一个对象具有软引用,如果内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。
     软引用最适合用来缓存。
     当系统内存不足的时候,缓存中的内容是可以被释放的。比如考虑一个图像编辑器的程序。该程序会把图像文件的全部内容都读取到内存中,以方便进行处理。而用户也可以同时打开多个文件。当同时打开的文件过多的时候,就可能造成内存不足。如果使用软引用来指向图像文件内容的话,垃圾回收器就可以在必要的时候回收掉这些内存。

3. 弱引用(Weak Reference)
     如果一个对象具有弱引用,在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了具有弱引用的对象,不管当前内存空间是否足够,都会回收它的内存。
     所以,具有弱引用的对象拥有更短暂的生命周期,以上就是和软引用的区别之处。
     当然,垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只有弱引用的对象。

      弱引用的作用在于解决强引用所带来的对象之间在存活时间上的耦合关系。弱引用最常见的用处是在集合类中,尤其在哈希表中。哈希表的接口允许使用任何Java对象作为键来使用。当一个键值对被放入到哈希表中之后,哈希表对象本身就有了对这些键和值对象的引用。如果这种引用是强引用的话,那么只要哈希表对象本身还存活,其中所包含的键和值对象是不会被回收的。如果某个存活时间很长的哈希表中包含的键值对很多,最终就有可能消耗掉JVM中全部的内存。
     对于这种情况的解决办法就是使用弱引用来引用这些对象,这样哈希表中的键和值对象都能被垃圾回收。Java中提供了WeakHashMap来满足这一常见需求。

4. 幽灵引用(Phantom Reference)
     幽灵引用也称虚引用,顾名思义,就是形同虚设,它与其他几种引用有很大的不同,幽灵引用并不会决定对象的生命周期。如果一个对象仅持有幽灵引用,那么它就和没有任何引用一样,在任何时候都可能被回收。
     它有一个最大的特点,它的get()方法永远返回null。
     幽灵引用主要用来跟踪对象被垃圾回收的活动。所以,幽灵引用与软引用和弱引用的一个区别就是:幽灵引用必须和引用队列(Reference Queue)联合使用。
     当垃圾回收器准备回收一个对象时,如果发现它还有幽灵引用,就会在回收对象的内存之前,把这个幽灵引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了幽灵引用,来了解被引用的对象是否要被垃圾回收。程序如果发现某个幽灵引用已经被加入到引用队列中,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

     这里介绍Java提供的对象终止化机制(finalization)。在Object类里面有个finalize方法,其设计的初衷是在一个对象被真正回收之前,可以用来执行一些清理的工作。因为Java并没有提供类似C++的析构函数一样的机制,就通过 finalize方法来实现。但是问题在于垃圾回收器的运行时间是不固定的,所以这些清理工作的实际运行时间也是不能预知的。幽灵引用(phantom reference)可以解决这个问题。在创建幽灵引用PhantomReference的时候必须要指定一个引用队列。当一个对象的finalize方法已经被调用了之后,这个对象的幽灵引用会被加入到队列中。通过检查该队列里面的内容就知道一个对象是不是已经准备要被回收了。
     幽灵引用及其队列的使用情况并不多见,主要用来实现比较精细的内存使用控制,这对于移动设备来说是很有意义的。程序可以在确定一个对象要被回收之后,再申请内存创建新的对象。通过这种方式可以使得程序所消耗的内存维持在一个相对较低的数量。

5. 引用队列(Reference Queue)
     在有些情况下,程序会需要在一个对象的可达到性发生变化的时候得到通知。比如某个对象的强引用都已经不存在了,只剩下软引用或是弱引用。但是还需要对引用本身做一些的处理。典型的情景是在哈希表中。引用对象是作为WeakHashMap中的键对象的,当其引用的实际对象被垃圾回收之后,就需要把该键值对从哈希表中删除。有了引用队列(ReferenceQueue),就可以方便的获取到这些弱引用对象,将它们从表中删除。在软引用和弱引用对象被添加到队列之前,其对实际对象的引用会被自动清空。通过引用队列的poll/remove方法就可以分别以非阻塞和阻塞的方式获取队列中的引用对象。

0 0
原创粉丝点击