Java 引用分类:StrongReference、SoftReference、WeakReference、PhantomReference
一,定义
在Java中,引用的定义是:如果reference类型的数据中存储的数值代表的是另一块内存的起始地址,就称这块内存代表着一个引用。后面在JDK1.2开始,引用的概念被扩充,引用被分为强引用(StrongReference)、软引用(SoftReference)弱引用、(WeakReference)、虚引用(PhantomReference)。这四种引用的强度关系:强引用>软引用>弱引用>虚引用。
1,强引用:这种引用就是我们在代码中最常用的,类似于“Object o = new Object()”,这个“o”引用就是强引用,只要强引用还存在,GC永远不会回收掉被引用的对象。
2,软引用:软引用是用来描述那些有用但非必须的对象,在系统发生内存溢出之前会对这些对象进行回收,也就是说内存不足就会回收这些对象,如果内存足够,即使手动GC也不会回收被软件引用指向的对象。
3,弱引用:弱引用用来描述非必须对象,强度比软引用更弱,当GC工作时,不管当前内存是否足够,都会回收只被弱引用指向的对象。
4,虚引用:与其他几种引用不同,虚引用不会影响对象的生存时间,也不能通过虚引用来获得一个对象的实例,它唯一的目的就是对象被回收时能收到一个通知。
二,实例说明
说了几种引用的概念,我们结合一些实例来说明他们各自的特性。
public class MyClass {
public static void main(String[] agrs){
MyClass myClass = new MyClass(20,"Zhang san");
SoftReference<MyClass> softReference = new SoftReference<MyClass>(new MyClass(15,"Li si"));
WeakReference<MyClass> weakReference = new WeakReference<MyClass>(new MyClass(10,"Wang er"));
PhantomReference<MyClass> phantomReference = new PhantomReference<>(new MyClass(5,"Ma zi"), new ReferenceQueue<>()); System.out.println("strong reference myClass = " + myClass);
System.out.println("soft reference get: " + softReference.get());
System.out.println("weak reference get: " + weakReference.get());
System.out.println("phantom reference get: " + phantomReference.get()); } private int age;
private String name; public MyClass(int age, String name){
this.age = age;
this.name = name;
} @Override
public String toString() {
return "name[" + this.name + "] age[" + this.age + "]";
} @Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalize method executed...." + this);
}
}
我们先看上面的例子,一个测试类,main()方法中定义了四个变量,分别是强引用、软引用、弱引用、虚引用,我们看下运行后的打印信息
strong reference myClass = name[Zhang san] age[20]
soft reference get: name[Li si] age[15]
weak reference get: name[Zhang san] age[20]
phantom reference get: null
从打印信息我们可以得知,虚引用虽然指向了一个对象,但是通过该引用得到的对象是null,这就验证了前面我们说的,不能通过虚引用得到对象的实例。
接下来,我们做点修改,加上显示调用垃圾回收,主要修改如下:
public static void main(String[] agrs){
MyClass myClass = new MyClass(20,"Zhang san");
SoftReference<MyClass> softReference = new SoftReference<MyClass>(new MyClass(15,"Li si"));
WeakReference<MyClass> weakReference = new WeakReference<MyClass>(new MyClass(10,"Wang er"));
PhantomReference<MyClass> phantomReference = new PhantomReference<>(new MyClass(5,"Ma zi"), new ReferenceQueue<>()); System.gc();
System.out.println("strong reference myClass = " + myClass);
System.out.println("soft reference get: " + softReference.get());
System.out.println("weak reference get: " + weakReference.get());
System.out.println("phantom reference get: " + phantomReference.get()); }
运行结果如下:
strong reference myClass = name[Zhang san] age[20]
finalize method executed....name[Ma zi] age[5]
finalize method executed....name[Wang er] age[10]
soft reference get: name[Li si] age[15]
weak reference get: null
phantom reference get: null
从结果中我们可以看到,当显示调用垃圾回收时,弱引用和虚引用对象都被回收了,这说明弱引用和虚引用指向的对象在发生GC时一定会被回收。但强引用和软引用指向的对象并没有被回收。我们接着做些修改,修改如下:
public static void main(String[] agrs){
MyClass myClass = new MyClass(20,"Zhang san");
SoftReference<MyClass> softReference = new SoftReference<MyClass>(new MyClass(15,"Li si"));
WeakReference<MyClass> weakReference = new WeakReference<MyClass>(new MyClass(10,"Wang er"));
PhantomReference<MyClass> phantomReference = new PhantomReference<>(new MyClass(5,"Ma zi"), new ReferenceQueue<>());
myClass = null;
System.gc();
System.out.println("strong reference myClass = " + myClass);
System.out.println("soft reference get: " + softReference.get());
System.out.println("weak reference get: " + weakReference.get());
System.out.println("phantom reference get: " + phantomReference.get()); }
同样看下运行的结果
strong reference myClass = null
finalize method executed....name[Zhang san] age[20]
finalize method executed....name[Ma zi] age[5]
finalize method executed....name[Wang er] age[10]
soft reference get: name[Li si] age[15]
weak reference get: null
phantom reference get: null
可以看出这个时候,强引用指向的对象被回收了,这是因为我们把myClass引用置空了,也就是说name为张三,age为20的对象没被引用了,当发生GC的时候,该对象就会被回收。
三,总结
强引用指向的对象如果被引用,发生GC时是不会被回收的,除非该对象没有被引用;软引用指向的对象在发生GC时不一定会被回收,该对象会被回收的条件是内存不足;弱引用和虚引用指向的对象在发生GC时一定会被回收,此外通过虚引用得不到引用的对象实例。
Java 引用分类:StrongReference、SoftReference、WeakReference、PhantomReference的更多相关文章
- Java之引用类型分析(SoftReference/WeakReference/PhantomReference)
引言: 即使对于Java的很多老鸟来说,如果忽然问他引用的类型,大概率是一脸茫然,不知所措的-.Java中的引用还分类型,神马情况??? 本文将针对这些类型进行分析,帮助您一文知所有类型. Java的 ...
- 4种引用与垃圾回收 :StrongReference, SoftReference, WeakReference , PhantomReference
- Java引用总结--StrongReference、SoftReference、WeakReference、PhantomReference
Java引用总结--StrongReference.SoftReference.WeakReference.PhantomReference 1 Java引用介绍 Java从1.2版本开始引入了4种引 ...
- Reference SoftReference WeakReference PhantomReference Cleaner 的研究与实践
最近在看netty的时候看到直接内存的相关概念,为了更详细的了解一下具体原理,搜到了一篇不错的文章 http://lovestblog.cn/blog/2015/05/12/direct-buffer ...
- Java核心技术-高级特性(2)- SoftReference, WeakReference and PhantomReference
Java.lang.ref 是 Java 类库中比较特殊的一个包,它提供了与 Java 垃圾回收器密切相关的引用类.这些引用类对象可以指向其它对象,但它们不同于一般的引用,因为它们的存在并不防碍 Ja ...
- Java 引用 WeakReference
Reference 是一个抽象类,而 SoftReference,WeakReference,PhantomReference 以及 FinalReference 都是继承它的具体类.接下来我们来分别 ...
- 你不知道的Java引用
什么是引用 引用就是保存着一块地址(门牌号)的对象,就像C语言的指针那样,引用可以传递某个数据的地址,如果我们想拿到某一条数据,就要先找到他的地址,然后告诉计算机我去拿这个地址的数据,最后计算机就 ...
- Java引用详解-StrongReference SoftReference WeakReference PhantomReference
1 Java引用介绍 Java从1.2版本开始引入了4种引用,这4种引用的级别由高到低依次为: 强引用 > 软引用 > 弱引用 > 虚引用 ⑴强引用(StrongR ...
- 强引用(StrongReference)、弱引用(WeakReference)、软引用(SoftReference)、虚引用(PhantomReference)
1.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.如下: Object o=new Object(); // 强引用 当内存空间 ...
随机推荐
- 1、开篇:公司管理经验谈 - CEO之公司管理经验谈
作为一家IT公司的CEO,我很高兴与大家通过博文的方式进行沟通交流.一方面能够将自己的成长之路以博文的方式记录下来,另一方面是能够与大家交朋友,与大家沟通公司管理方面的知识和经验. 首先,笔者在200 ...
- 烂泥:python2.7和python3.5源码安装
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 前几天在centos6.6安装ansible时,一直提示python版本不对,导致不能安 ...
- python3: error while loading shared libraries: libpython3.5m.so.1.0: cannot open shared object file: No such file or directory
安装python3遇到报错: wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz ./configure --prefix=/u ...
- 常用算法——排序(二)
简单选择排序法 选择排序(Selection Sort)的基本思想:对n个记录进行扫描,选择最小的记录,将其输出,接着在剩下的n-1个记录中扫描,选择最小的记录将其输出,--不断重复这个过程,直到只剩 ...
- HTML 学习笔记 JavaScript(call方法详解)
http://www.cnblogs.com/f-dream/p/4950918.html
- Linux计划任务.md
crond crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程 ...
- html5标签知多少
此文为前段时间团队研究会出品,与小伙伴兮兮圆一起研究的成果,意外地上了公司km的今日推荐,今日挪过来,为新开张的博客先暖暖场吧. 一.常用标签 <header>.<footer> ...
- [LeetCode] Design Tic-Tac-Toe 设计井字棋游戏
Design a Tic-tac-toe game that is played between two players on a n x n grid. You may assume the fol ...
- [LeetCode] Divide Two Integers 两数相除
Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...
- JavaScript基础语法
首先,JavaScript的基本语法是以名为ECMAScript的伪语言定义的,理解ECMAScript的细节就是理解它在浏览器中实现的关键,目前大多数浏览器都遵循了ECMAScript第3版的,但是 ...