在java中,大致有以下几种引用类型,强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)、虚引用(PhantomReference

--- 强引用-FinalReference

  强引用是平时最常见的,类似诸如

 String a  = new String("helloworld");

这个a就是强引用类型,最主要的一点是:即使内存不够,程序宁愿抛出异常,也不会去进行回收

--- 软引用-SoftReference

软引用(softReference)在强度上弱于强引用,通过类 SoftReference 来表示。它的作用是告诉垃圾回收器,程序中的哪些对象是不那么重要,当内存不足的时候是可以被暂时回收的。当JVM中的内存不足的时候,垃圾回收器会释放那些只被软引用所指向的对象。如果全部释放完这些对象之后,内存还不足,才会抛出OutOfMemory错误。软引用非常适合于创建缓存。当系统内存不足的时候,缓存中的内容是可以被释放的。

  比如考虑一个图像编辑器的程序。该程序会把图像文件的全部内容都读取到内存中,以方便进行处理。而用户也可以同时打开多个文件。当同时打开的文件过多的时候,就可能造成内存不足。如果使用软引用来指向图像文件内容的话,垃圾回收器就可以在必要的时候回收掉这些内存。

--- 弱引用-WeakReference

弱引用的强度弱于软引用,简单来说就是,一旦某个引用不需要使用的时候,JVM就会自动回收,而程序员本身无须做其他操作,在Java源码中的java.util.WeakHashMap中的key就是使用弱引用

--- 虚引用-PhantomReference

在介绍虚引用之前,要先介绍Java提供的对象终止化机制(finalization)。在Object类里面有个finalize方法,其设计的初衷是在一个对象被真正回收之前,可以用来执行一些清理的工作。因为Java并没有提供类似C++的析构函数一样的机制,就通过 finalize方法来实现。但是问题在于垃圾回收器的运行时间是不固定的以这些清理工作的实际运行时间也是不能预知的。虚引用(phantom reference)可以解决这个问题。在创建虚引用PhantomReference的时候必须要指定一个引用队列。当一个对象的finalize方法已经被调用了之后,这个对象的虚引用会被加入到队列中。通过检查该队列里面的内容就知道一个对象是不是已经准备要被回收了。

举个栗子

package com.xxg;

import java.io.Serializable;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference; public class PhantomBuffer { public static void main(String[] args) throws InterruptedException {
//强引用类型:变量strongReference对对象的引用为强引用
User strongReference = new User("strongReference");
System.out.println(strongReference.getName()); //strongReference //弱引用类型: 变量weakReference对对象的引用为弱引用
WeakReference<User> weakReference = new WeakReference<User>(new User("weakReference"));
System.out.println(weakReference.get().getName()); //weakReference //弱引用测试
System.out.println(weakReference.get());//user对象
System.gc();//调用jvm 垃圾回收器(不一定立即执行)
Thread.sleep(10000);//阻塞线程10秒,等待gc执行
System.out.println(weakReference.get()); //null //软引用类型: 变量softReference对对象的引用为软引用
SoftReference<User> softReference = new SoftReference<User>(new User("softReference"));
System.out.println(softReference.get().getName()); //softReference
System.out.println(softReference.get()); //com.xxg.PhantomBuffer$User@6d06d69c //虚引用类型:
PhantomReference<User> phantomReference = new PhantomReference<User>(new User("phantomReference"), new ReferenceQueue<>());
System.out.println(phantomReference.get()); //null
} static class User implements Serializable{
private static final long serialVersionUID = 1L;
private String name; public User(String name){
this.name = name;
} public String getName(){
return name;
} public void setName(String name)
{
this.name = name;
}
}
}

参考资料:Java 四种引用介绍及使用场景

最新文章

  1. setAttribute,,,getAttribute,,,,
  2. 在线读取Mongodb数据库下载EXCEL文件
  3. SharePoint 2013 开发——开发自定义操作APP
  4. MySQL优化技巧之四(数据库设计中的一些技巧)
  5. jsoup:解析HTML用法小结
  6. jQuery.fn
  7. Python环境变量配置问题
  8. CLR_Via_C#学习笔记之枚举
  9. 虚拟主机VPS区别:DigitalOcean优惠码
  10. PCB信号集
  11. 基础拾遗-----mongoDB操作
  12. Text-插入图片
  13. 禁止root登陆sshd/并修改默认端口号
  14. linux screen 工具
  15. matlab中randn(‘state’)
  16. C++高质量编程笔记
  17. oracle 忘记了scott用户的密码,该怎么修改
  18. 查找网内活跃IP和自动传输文本
  19. 关于XSHM(Cross-Site History Manipulation)
  20. 面向 B 端的产品经理

热门文章

  1. HDU6024:Building Shops(DP)
  2. python 可迭代对象与迭代器之间的转换
  3. CF1059D Nature Reserve(二分)
  4. JAVA多线程(二) 并发队列和阻塞队列
  5. c库函数-字符串
  6. HAL之定时器
  7. 三色灯渐变DIY制作
  8. 关于c#的结构体struct与class的区别
  9. css 尺寸、边框、内边距、背景以及css Sprite
  10. mysql 查询数据库参数命令