Java引用类型分类以及详解

Java引用类型分类以及详解

- Java引用类型概述

在JVM之中再好的算法,也敌不过一个好烂的程序员。一个程序要想写好有两点:按照开发标准进行、请写有用代码。
而对于垃圾的产生与回收的处理之中,要想进行更好的控制,就必须清楚的掌握Java中的四种引用方式。
强引用(Strong Reference):即使进行了多次的GC回收,即使JVM真的已经不够用了,即使JVM最终不得已抛出了OOM错误,那么该引用继续抢占;
软引用(Soft Reference):当内存空间不足时,可以回收此内存空间。如果充足则不回收,可以用其完成缓存的一些处理操作开发。
缓存:保证数据更快的操作(读取)。是不重要的数据。可以作为牺牲来释放空间。
弱引用(Weak Reference):不管内存是否紧张,只要一出现GC处理,则立即回收。
幽灵引用(Phantom Reference):和没有引用是一样的。
比如HashMap根据key取得值,设置key值为null和不设置key值的效果是一样的。

  • 强引用

强引用是Java默认支持的一种操作模式,也就是说在引用的处理其间,即使出现有GC,即使内存不足,该引用的数据也不会被回收。

范例:观察强引用:

Java引用类型分类以及详解_第1张图片
这个流程就叫做强引用。在之前所编写的所有操作都属于强引用,而强引用只有全部的对象都断开连接之后,才可能称为垃圾空间,才有可能被回收。而即使有一个对象引用此空间,那么该对象也不会被回收。
在多线程状态下,即使产生多个引用对象,空间也不会被回收。

Java引用类型分类以及详解_第2张图片
每个线程都会出现OOM
强引用并不是造成OOM的关键性因素,正常来讲,你每一个用户(线程)操作完成后,该对象都可以被很容易的进行回收,不必强制性进行回收。

  • 软引用
    软引用指的是当内存不足的时候才进行GC的空间释放,但是如果要想使用软引用必须单独使用特殊的处理类:
    java.lang.ref.SoftReference,该类的定义如下:

Java引用类型分类以及详解_第3张图片
除了强引用,其它引用必须借助特殊类来完成。

Java引用类型分类以及详解_第4张图片
软引用的类继承了Reference的引用父类。
这个类下有三个引用:
Java引用类型分类以及详解_第5张图片

在软引用之中如果想要进行引用的处理操作,则可以使用如下的方法完成:

1.构造方法:public SoftReference(T reference);
2.取得引用的数据:public T get();

范例:观察软引用:
Java引用类型分类以及详解_第6张图片
软引用与强引用相比,最大的特点在于:软引用中保存的内容如果在内存富裕的时候会继续保留,内存不足会作为第一批的丢弃者进行垃圾空间的释放。
在开发中,可以利用软引用可以实现高速缓存组件。
缓存处理好了,你的程序写的才能达到高性能的第一步

  • 弱引用
    弱引用最大的特点就是一旦发生了GC的处理操作,则保存的引用内容将立即释放。弱引用使用“WeakReference”类来完成。
    java.lang.ref.WeakReference

范例:弱引用处理
Java引用类型分类以及详解_第7张图片

因为不执行GC,所以弱引用的对象并没有被释放。输出依然有值。
Java引用类型分类以及详解_第8张图片
输出为null;
一旦执行了GC,那么就需要进行内存空间的释放,在类集里面有一个与弱引用功能相似的Map集合WeakHashMap,它属于弱引用的一个实现。

Java引用类型分类以及详解_第9张图片

Java引用类型分类以及详解_第10张图片

whm中存放的都是匿名对象。
个人觉得使用WeakHashMap最大的好处是可以用它保存一些共享数据,这些共享数据如果长时间不使用,可以将其清空。

  • 引用队列
    在之前使用软引用和弱引用的时候都会发现有这样一个构造方法:
    SoftReference:
    Java引用类型分类以及详解_第11张图片
    WeakReference:
    Java引用类型分类以及详解_第12张图片
    java.lang.ref包中一共五各类:一个父类,三个子类,另外一个就是引用队列。

引用队列:待被砍掉的对象的集合点
如果要清楚引用队列,则首先必须知道对象的引用的强度。如果说按照现在的理解来讲:强引用的强度大于软引用,软引用大于弱引用。

Java引用类型分类以及详解_第13张图片
通过以上的图形分析可以发现,如果要想找到“对象5”,那么一共有两条对象的可及性的路径:
Java引用类型分类以及详解_第14张图片

在以上给出的引用的路径上,1到5是最强引用,但是由于其本身存在一个软引用,所以对象5对于整个的程序就属于软可及对象。
在java里面,如果某一个对象不属于强引用,那么就需要有一个专门的机制来清除那些不具有存在价值的对象(强对象才有价值)
所以这个时候如果保存有太多的无价值对象就会造成内存泄漏,那么为专门提供有一个引用队列,当某一个对象被垃圾回收后,则该对象会被保存到引用队列之中。

范例:观察引用队列的处理操作;
Java引用类型分类以及详解_第15张图片
在发生GC内存清理之前,此时引用队列中为null;
Java引用类型分类以及详解_第16张图片
此处必须断开强引用
执行完GC之后引用队列有内容。

引用队列里面保存的就是一个要准备被回收的对象的信息。

  • 幽灵引用(虚引用)
    幽灵引用指的是什么都不保存,但是又看起来像是保存了一样。
    这个的处理类java.lang.ref.PhantomReference。

范例:观察幽灵引用:
幽灵引用直接就把要保存的内容保存在了引用队列之中
Java引用类型分类以及详解_第17张图片

需要发生引用但是又不需要引用占用空间的时候。—采用幽灵引用。

你可能感兴趣的:(java基础知识点)