3妹:“如果华陀再世,崇洋都被医治,外邦来学汉字,激发我民族意识” 2哥:3妹不要只唱歌啊,跳起来啊, 刘畊宏女孩动起来! 3妹:我是属于头脑简单,四肢不发达的, 动动嘴皮子还行, 要我运动还是算了吧。 2哥:不运动不行啊,我们这行工作强度很大的, 身体是革命的本钱嘛。 3妹:好吧,等我先把这一章节学完就来运动。 2哥:在学什么呢,跟我说说 3妹:java对象的4种引用的区别,你看:
#对象在内存中的3种状态 1.可达状态 有一个及以上的变量引用着对象。 2.可恢复状态 已经没有变量引用对象了,但是还没有被调用finalize()方法。系统在回收前会调用finalize()方法,如果在执行finalize()方法时,重新让一个变量引用了对象,那么对象会变成可达状态,否则会变成不可达状态。 3.不可达状态 执行finalize()方法后,对象还是没有被其他变量引用,那么对象就变成了不可达状态。
对象的4种引用介绍
Java执行GC判断对象是否存活有两种方式其中一种是引用计数。 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象处于(reachable)可达状态,程序才能使用它。 从JDK 1.2版本开始,对象的引用被划分为4种级别,从而使程序能更加灵活地控制对象的生命周期。这4种级别由高到低依次为:强引用、软引用、弱引用和虚引用。
1.强引用
就是普通的变量对对象的引用,强引用的对象不会被系统回收。
Object strongReference = new Object();
如果强引用对象不使用时,显式地设置strongReference对象为null,从而使GC能够回收。
2.软引用
当内存空间足够时,软引用的对象不会被系统回收。当内存空间不足时,软引用的对象可能被系统回收。通常用于内存敏感的程序中。
// 强引用
String strongReference = new String("abc");
// 软引用
String str = new String("abc");
SoftReference<String> softReference = new SoftReference<String>(str);
软引用可以和一个引用队列(ReferenceQueue)联合使用。如果软引用所引用对象被垃圾回收,JAVA虚拟机就会把这个软引用加入到与之关联的引用队列中。
ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
String str = new String("abc");
SoftReference<String> softReference = new SoftReference<>(str, referenceQueue);
str = null;
// Notify GC
System.gc();
System.out.println(softReference.get()); // abc
Reference<? extends String> reference = referenceQueue.poll();
System.out.println(reference); //null
当内存不足时,垃圾收集线程会在虚拟机抛出OutOfMemoryError之前回收软引用对象,而且虚拟机会尽可能优先回收长时间闲置不用的软引用对象。对那些刚构建的或刚使用过的“较新的”软对象会被虚拟机尽可能保留,这就是引入引用队列ReferenceQueue的原因。
3.弱引用
引用级别比软引用低,对于只有软引用的对象,不管内存是否足够,在垃圾回收时, 都可能会被系统回收。
String str = new String("abc");
WeakReference<String> weakReference = new WeakReference<>(str);
str = null;
同样,弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
4.虚引用
虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。 虚引用主要用于跟踪对象被垃圾回收的状态,在垃圾回收时可以收到一个通知。 虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。
String str = new String("abc");
ReferenceQueue queue = new ReferenceQueue();
// 创建虚引用,要求必须与一个引用队列关联
PhantomReference pr = new PhantomReference(str, queue);
总结
Java中4种引用的级别和强度由高到低依次为:强引用 -> 软引用 -> 弱引用 -> 虚引用
当垃圾回收器回收时,某些对象会被回收,某些不会被回收。垃圾回收器会从根对象Object来标记存活的对象,然后将某些不可达的对象和一些引用的对象进行回收。
通过表格来说明一下,如下:
引用类型 | 被垃圾回收时间 | 用途 | 生存时间 |
---|
强引用 | 从来不会 | 对象的一般状态 | JVM停止运行时终止 | 软引用 | 当内存不足时 | 对象缓存 | 内存不足时终止 | 弱引用 | 正常垃圾回收时 | 对象缓存 | 垃圾回收后终止 | 虚引用 | 正常垃圾回收时 | 跟踪对象的垃圾回收 | 垃圾回收后终止 |
|