一、强引用

JAVA默认的引用类型,强引用,是在我们的开发工作当中普遍存在的。如果一个对象具有强引用,当内存空间不足的时候,java虚拟机宁可抛出OOM异常,也不会回收它来释放内存。但是我们可以将对象显示的赋值为null,则gc认为该对象不存在引用,这时就可以回收这个对象。具体什么时候收集这要取决于gc的算法。如果方法的内部有一个强引用,这个引用保存在栈中,而真正的引用内容(Object)保存在堆中。当这个方法运行完成后就会退出方法栈,则引用内容的引用不存在,这个Object会被回收。

    private static  void storongReference(){
Object obj=new Object();
Object obj2=obj;
obj=null;
System.gc();
System.out.println(obj2); //java.lang.Object@7ea987ac
}

二、软引用(SoftReference)

软引用是用来描述一些非必需但仍有用的对象。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。软引用通常用在对内存比较敏感的程序中,例如高速缓存区,mybatis就是用到了该方式。

/**
* @Auther: XL
* @Date: 2019/12/24 07:50
* @Description: -Xms10M -Xmx10M -XX:+PrintGCDetails
*/
public class SoftReferenceTest {
private volatile static Map<String,SoftReference> cacheMap=new ConcurrentHashMap<>();
public static void main(String [] args) throws Exception{
softReferenceNotAmple();
}
/**
* SoftReference内存不足就回收
*/
private static void softReferenceNotAmple(){
SoftReference reference;
for(int i=0;i<10;i++){
reference=new SoftReference(new byte[1024*1024*2]);
cacheMap.put("key:"+i,reference);
}
cacheMap.forEach((k,v)->{
System.out.println("key:"+k+ " value:"+v.get());
});
}
}

三、弱引用(WeakReference)

无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。

/**
* @Auther: XL
* @Date: 2019/12/24 08:02
* @Description:
*/
public class WeakReferenceTest {
private volatile static Map<String,WeakReference> cacheMap=new ConcurrentHashMap<>();
public static void main(String [] args){
weakReference();
} /**
* -Xms10M -Xmx10M -XX:+PrintGCDetails
* 5次循环5M内存足够使用,手动触发gc;内存被回收
*/
private static void weakReference(){
WeakReference reference;
for(int i=0;i<5;i++){
reference=new WeakReference(new byte[1024*1024*1]);
cacheMap.put("key:"+i,reference);
}
System.gc();
cacheMap.forEach((k,v)->{
System.out.println("key:"+k+ " value:"+v.get());
});
}
}

当一个 WeakReference 开始返回 null 时, 它所指向的对象已经准备被回收, 这时可以做一些合适的清理工作.   将一个 ReferenceQueue 传给一个 Reference 的构造函数, 当对象被回收时, 虚拟机会自动将这个对象插入到 ReferenceQueue 中, WeakHashMap 就是利用 ReferenceQueue 来清除 key 已经没有强引用的 entries.

四、虚引用(PhantomReference)

形同虚设,虚引用不会决定对象的生命周期,如果一个对象仅持有虚引用,那么他和没有任何引用一样,在任何时候都可能被垃圾收集器回收,他不能单独使用也不能通过他访问对象,虚引用必须和引用队列(ReferenceQueue)联合使用。

虚引用的作用:作用在于跟踪垃圾回收过程,在对象被收集器回收时收到一个系统通知。 当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在垃圾回收后,将这个虚引用加入引用队列,在其关联的虚引用出队前,不会彻底销毁该对象。 所以可以通过检查引用队列中是否有相应的虚引用来判断对象是否已经被回收了。使用虚引用的目的就是为了得知对象被GC的时机,所以可以利用虚引用来进行销毁前的一些操作,比如说资源释放等。这个虚引用对于对象而言完全是无感知的,有没有完全一样,但是对于虚引用的使用者而言,就像是待观察的对象的把脉线,可以通过它来观察对象是否已经被回收,从而进行相应的处理。虚引用有一个很重要的用途就是用来做堆外内存的释放,DirectByteBuffer就是通过虚引用来实现堆外内存的释放的。

/**
* @Auther: XL
* @Date: 2019/12/24 08:38
* @Description:
*/
public class PhantomReferenceTest {
public static void main(String [] args) throws Exception{
ReferenceQueue<TestObj> queue = new ReferenceQueue<>();
TestObj instanceA = new TestObj(); //创建对象
PhantomReference<TestObj> phantomRef = new PhantomReference<TestObj>(instanceA, queue); //创建phantom引用
System.out.println("gc前PhantomReference的引用:"+phantomRef.get());
System.out.println("gc前ReferenceQueue:"+queue.poll());
instanceA = null; // 不再使用对象
System.gc();
System.out.println("第一次gc后PhantomReference的引用:"+phantomRef.get());
System.out.println("第一次gc后ReferenceQueue:"+queue.poll());
Thread.sleep(1000);
System.gc();
System.out.println("第二次gc后PhantomReference的引用:"+phantomRef.get());
System.out.println("第二次gc后ReferenceQueue:"+queue.poll());
}
}
class TestObj{
@Override
protected void finalize() throws Throwable {
System.out.println("======"+this+"======");
super.finalize();
}
}
ReferenceQueue名义上是一个队列,但实际内部并非有实际的存储结构,它的存储是依赖于内部节点之间的关系来表达。可以理解为queue是一个类似于链表的结构,这里的节点其实就是reference本身。可以理解为queue为一个链表的容器,其自己仅存储当前的head节点,而后面的节点由每个reference节点自己通过next来保持即可。

ReferenceQueue一般用来与SoftReference、WeakReference或者PhantomReference配合使用,将需要关注的引用对象注册到引用队列后,便可以通过监控该队列来判断关注的对象是否被回收,从而执行相应的方法。

主要使用场景:

1、使用引用队列进行数据监控,类似前面栗子的用法。

2、队列监控的反向操作

JAVA的引用类型的更多相关文章

  1. Java之引用类型分析(SoftReference/WeakReference/PhantomReference)

    引言: 即使对于Java的很多老鸟来说,如果忽然问他引用的类型,大概率是一脸茫然,不知所措的-.Java中的引用还分类型,神马情况??? 本文将针对这些类型进行分析,帮助您一文知所有类型. Java的 ...

  2. Java/Android引用类型及其使用分析

    Java/Android中有四种引用类型,分别是: Strong reference     - 强引用Soft Reference        - 软引用Weak Reference      - ...

  3. Java笔记--引用类型的使用

    使用引用类型的一般步骤: 1.导包:指定需要使用的目标在什么位置,在publicclass之前一行写代码 import 包名路径 2.创建:通常需要创建之才能使用,格式: 数据类型 变量名称 = ne ...

  4. GuavaCache学习笔记二:Java四大引用类型回顾

    前言 上一篇已经讲了,如何自己实现一个LRU算法.但是那种只是最基本的实现了LRU的剔除策略,并不能在生产中去使用.因为Guava Cache中使用的是SoftReference去做的value实现, ...

  5. Java的引用类型的内存分析

    一. jdk的内存:jdk的bin目录常见命令 1. javac.exe:编译java源代码的,生成java字节码文件(*.class) 2. java.exe:启动一个jvm,来运行指定class字 ...

  6. Java中引用类型、对象的创建与销毁

    引用类型 在java中,除了基本数据类型之外的,就是引用数据类型了,引用指的是对象的一个引用,通过引用可以操作对象,控制对象,向对象发送消息. 简单来说,引用可以访问对象的属性,并调用对象的方法 创建 ...

  7. java中 引用类型 和 基本类型 有何区别?

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的(对象从中分配空间.这些对象通过new.newa ...

  8. Java基础——引用类型作为形参与返回值

    一.具体类名作为形参与返回值 1.方法的形参是类名,其实需要的是该类的对象 比如有一个具体的猫类,我使用另一个类使用猫类的方法 public class CatOperator {   public ...

  9. WeakHashMap和Java引用类型详细解析

    WeakHashMap是种弱引用的HashMap,这是说,WeakHashMap里的key值如果没有外部强引用,在垃圾回收之后,WeakHashMap的对应内容也会被移除掉. 1.1 Java的引用类 ...

随机推荐

  1. util.date

    package com.sxt.utils.date1; import java.util.Date; /* * util.date */ public class TestDate { public ...

  2. CSS长度单位:px和pt的区别

    先搞清基本概念:px就是表示pixel,像素,是屏幕上显示数据的最基本的点:而pt就是point,是印刷行业常用单位,等于1/72英寸. 这样很明白,px是一个点,它不是自然界的长度单位,谁能说出一个 ...

  3. 关于Java语言for循环内外变量定义的问题

    今天看书时,看到一个代码,一个在循环外面没有用的变量,后即有了我的问题,在后面: 我的问题: 变量循环内定义,例如:while(true){String splitStr = null;}这“些”个s ...

  4. display:flex; justify-content:space-between; 最后一行显示内容无法靠左显示

    给父元素添加同每行展示列数一样(展示列表最多的)的子元素. 子元素设置样式: width:同子元素一样的width : height:0;

  5. laravel 使用create 报错 MassAssignmentException

    在使用:   模型:create时报错, Add [name] to fillable property to allow mass assignment on [App\AdminUser].,因为 ...

  6. GPU选型

    1-基本概念 显存带宽     是指显示芯片与显存之间的数据传输速率,它以字节/秒为单位.显存带宽是决定显卡性能和速度最重要的因素之一. 2-常见GPU性能参数 GPU型号 单卡显存 cuda 计算能 ...

  7. BiLSTM-CRF学习笔记(原理和理解) 维特比

    BiLSTM-CRF 被提出用于NER或者词性标注,效果比单纯的CRF或者lstm或者bilstm效果都要好. 根据pytorch官方指南(https://pytorch.org/tutorials/ ...

  8. PyTorch官方中文文档:torch.optim 优化器参数

    内容预览: step(closure) 进行单次优化 (参数更新). 参数: closure (callable) –...~ 参数: params (iterable) – 待优化参数的iterab ...

  9. 【u228】圣诞树

    [问题描述] 圣诞特别礼物挂在一棵圣诞树上,这棵树有n层,每层有一件礼物,每件礼物都有一个价值,有的礼物还有一些连结线,与下层的礼物相连,领取礼物的规则如下:任选一件礼物,它的下面如果有连结线,则可以 ...

  10. vue-cil 打包爬坑(解决)

    1.打包成功不报错,但是打开页面啥都没有?  解决:文件位置:config目录下index.js文件更改assetsPublicPath属性:文件里面有两个assetsPublicPath属性,也就是 ...