Java中Soft,Weak,Phantom应用的区别和使用

Java 1.2版本之后加入的这三个引用类型其实是对java中对象生命周期的一个增强,使得java对象的生命周期更加丰富。这三个引用类型主要在Java虚拟机的垃圾收集阶段发挥作用。
垃圾收集器对待软、弱和影子对象的方法不同,因为每一种都被设计用来为程序提供不同的服务。软引用使你可以创建内存中的缓存。它与程序的整体内存需求相关。弱引用使你可以创建规范映射,比如哈希表,它的关键字和值在没有其他程序部分的引用时可以从隐射中清除,而影子引用使你可以实现除终结方法以外的更加复杂的临终清理政策。
使用一个软引用或者弱引用的引用目标,可以调用引用对象的get()方法。如果引用目标还没有被清除,则会得到对引用目标的一个强引用,就可以用通常的办法去使用它了。如果引用目标已经被清除,则会返回null。如果调用影子引用对象的get()方法,那么无论如何只能得到null,即使引用对象还没有被清除。因为影子可触及状态只有经过可复活状态之后才能获得,一个影子引用对象没有提供任何放啊飞来访问它的引用目标。调用影子引用对象的get()方法只能得到null,即使影子引用还没有清除。因为,如果它返回一个可触及对象的强引用,实际上它就复活了这个对象。这就是说,如果一个对象达到了影子可触及状态,它就无法被复活了。
虚拟机的实现需要在抛出OutOfMemoryError之前清除软引用,但在其他情况下可以自行选择清理的时间或者是否清除它们。一般的实现都会内存块耗尽时才去清除软引用对象,而且清除的时候是先清除老的而不是新的。因为这样才能最好地发挥软引用作为内存缓存的作用。
软引用可以让你在内存中缓存那些需要从外部数据源费时取回的数据,比如文件、数据库链接等等。所以只要虚拟内存有足够的内存,那就会在堆中保存所有的强应用数据和软引用数据。只有当内存不够用时,垃圾收集器才会去清除软引用,回收被软引用及其引用的对象或者数据占据的空间。下一次程序需要使用这个对象或者数据的时候,就必须重新进行加载。同时,虚拟机就有更多的空间来调整强引用或者其他软引用需要的内存。这对于内存比较紧张,而又要求有较高性能的情况比较适用。
弱引用类似于软引用,只不过垃圾收集器必须在判断出对象处于弱可触及状态时立即清除弱引用所引用的对象。弱引用使得你可以用关键字和值来创建规范映射。java.util.WeabHashMap类就是用弱引用提供这样的规范映射。在WeakHashMap中,关键字对象是通过一个关联到引用队列的弱引用实现的。如果垃圾收集器判定某个关键字对象是弱可触及的,它就会清除引用并且把任何弱引用到该对象的引用加入到各自的队列中(引用队列)。下一次当WeakHashMap被访问时,它从引用队列里面拉出所有垃圾收集器放在那里的弱引用对象,然后清除WeakHashMap中任何关键字属于队列中弱引用的键-值对。这就是说,如果是把一个键-值对加入到WeakHashMap,在程序显示地使用remove()方法移出它或者垃圾收集器发现关键字对象是弱可触及之前,它会一直保留在WeakHashMap中。这对于内存有限的情况比较适用,因为在java中,如果将对象放在一般的HashMap中,虚拟机会认为该对象是强可触及的,即使没有除了HashMap对象之外的其他对象使用到该对象。使用弱引用时,就可以避免这种情况。虚拟机一旦发现弱引用的对象没有被其他对象使用,就会垃圾收集他们,节约内存。
影子可触及性表示对象即将被回收。当垃圾收集器判定影子引用对象的引用目标处于影子可触及状态时,它把该影子引用加入到所关联的引用队列。(和软引用对象、弱引用对象不同,软引用对象和弱引用对象可以在创建时选择不和一个引用队列关联,而影子引用对象没有一个关联的引用队列就无法创建实例。)可以利用引用队列中影子引用的到达来触发一些你希望在对象生命周期的最后时刻需要完成的动作(通过注册,在影子引用到达队列时得到虚拟机发出的异步信号)。因为无法获得对影子可触及对象的强引用(get()方法总是返回null)所以无法完成那些需要访问影子目标的实例变量的动作。在完成了影子可触及对象的临终清理之后,必须调用只想它的影子引用对象的clear()方法。调用一个影子引用对象的clear()方法是对它的引用对象的致命一击,把引用目标从影子可触及状态导向它的终点:不可触及状态。([color=red]所以说,利用影子引用是没有办法操作被引用对象本身的,只能做一些与被引用对象相关的,但是又不需要被引用对象参与的善后处理动作。因此,影子引用更像是一个java虚拟机对外暴露的终结对象前的回调标记接口。通过这个接口,你可以在一个对象被销毁之前得到通知,然后做一些处理。这可能是Sun因为考虑到java虚拟机的垃圾回收机制不受程序员控制的关系而衍生出来的一种这种方案。[/color])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值