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()方法是对它的引用对象的致命一击,把引用目标从影子可触及状态导向它的终点:不可触及状态。(
所以说,利用影子引用是没有办法操作被引用对象本身的,只能做一些与被引用对象相关的,但是又不需要被引用对象参与的善后处理动作。因此,影子引用更像是一个java虚拟机对外暴露的终结对象前的回调标记接口。通过这个接口,你可以在一个对象被销毁之前得到通知,然后做一些处理。这可能是Sun因为考虑到java虚拟机的垃圾回收机制不受程序员控制的关系而衍生出来的一种这种方案。)
分享到:
相关推荐
从JDK 1.2版本开始,Java引入了四种不同级别的引用:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。这些引用类型提供了灵活的内存管理策略,允许...
为了更好地理解和控制对象的生命周期,Java提供了四种不同类型的引用:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)以及虚引用(Phantom Reference)。每种引用都有其特定的...
在Java编程语言中,引用类型是理解内存管理的关键概念之一。本教程将深入探讨Java中的“强引用”...通过实践这些示例,你将能够熟练掌握如何在Java应用程序中有效地使用各种引用,以提升程序的性能和内存管理能力。
通常,Java有四种类型的引用:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。强引用是最常见的类型,当对象被强引用持有时,垃圾回收器不会回收...
本文将深入探讨Java中三种特殊的引用类型——软引用(Soft Reference)、弱引用(Weak Reference)以及虚引用(Phantom Reference),并分析它们如何帮助我们更好地管理内存资源。 #### 二、基础知识回顾 在深入了解这三...
在Java编程语言中,引用是连接对象和内存空间的关键概念。本示例“java引用的demo”将深入探讨四种不同类型的引用:强引用、软引用、弱引用和虚引用。这些引用类型对于理解和优化内存管理至关重要,特别是在Android...
在Java中,对象引用主要分为四种类型:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)以及虚引用(Phantom Reference)。 - **强引用(Strong Reference)**: 这是最常用的引用...
在Java编程语言中,`Reference`类是一个非常特殊且重要的概念,它超出了常规的引用类型,如`Object`或数组引用。`Reference`类及其子类主要用于处理对象的软引用、弱引用和虚引用,这些引用类型在内存管理,特别是...
在Java开发中,熟练掌握这些引用类型的概念和使用场景,可以帮助我们编写出更加高效、健壮的代码。同时,理解垃圾收集的工作原理也非常重要,因为这直接影响到程序的性能和稳定性。在实际开发中,合理利用这些引用...
在Java中,对象的创建、使用和销毁是由JVM自动管理的,主要通过垃圾回收机制来实现。垃圾回收器会定期检查不再被引用的对象,并进行回收,从而释放内存空间。但是,这并不意味着程序员可以完全忽视内存管理,因为...
深入理解 Java 虚拟机笔记 ...Java 中的虚方法表用于存储虚方法的信息,包括方法的名称、描述符和方法体。 Java 内存模型(JMM) Java 内存模型(JMM)是 Java 语言的内存模型,用于定义 Java 程序的内存行为。
Java垃圾回收机制是Java虚拟机(JVM)中的一种自动管理内存的机制,它可以自动地将不再使用的对象从内存中回收,以释放更多的内存空间供其他对象使用。本文将详细介绍Java垃圾回收机制的工作原理、各个阶段的执行...
这种机制不仅提升了Java应用程序对内存使用的灵活性,还为实现某些特殊功能提供了便利,比如内存敏感的缓存管理和对象生命周期监控等。 #### 二、强引用 强引用是最常见也是最常用的引用类型。如果一个对象被强...
- **最佳实践**:尽管`finalize()` 方法可以用来执行清理操作,但现代Java实践中更推荐使用`try-with-resources`语句或其他资源管理机制,因为它们更加可靠且易于控制。 #### 垃圾回收相关API 为了更好地了解和...
### Java 常见的四种引用详解 #### 引言 在Java中,为了更好地管理对象的生命周期,从JDK 1.2开始引入了四种不同级别的引用类型:强引用、软引用、...正确理解和使用这些引用类型对于优化Java应用程序的性能至关重要。
10. 泛型(Generics):泛型引入了类型参数的概念,允许在类、接口和方法中使用类型参数,提高了代码的类型安全性和重用性。泛型可以应用于集合框架,限制元素类型,避免了类型转换的麻烦。 以上知识点涵盖了Java...
- **本地方法栈(Native Method Stacks)**:与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则是为虚拟机使用到的Native方法服务。 - **Java堆(Java Heap)**:所有...
为了避免这些问题,建议避免在安全关键代码中使用`finalize()`方法,而采用更可靠的资源管理技术,如通过`try-with-resources`语句自动关闭资源,或者使用`SoftReference`、`WeakReference`和`PhantomReference`等...