java的几种引用
强引用:无论内存是否足够,不会回收。
软引用:内存不足时,回收该引用关联的对象。
弱引用:垃圾回收时,无论内存是否足够,都会回收。
虚引用:任何时候都可能被垃圾回收器回收。
在Java中,虽然不需要程序员手动去管理对象的生命周期,但是如果希望某些对象具备一定的生命周期的话(比如内存不足时JVM就会自动回收某些对象从而避免OutOfMemory的错误)就需要用到软引用和弱引用了。
从Java SE2开始,就提供了四种类型的引用:强引用、软引用、弱引用和虚引用。Java中提供这四种引用类型主要有两个目的:第一是可以让程序员通过代码的方式决定某些对象的生命周期;第二是有利于JVM进行垃圾回收。下面来阐述一下这四种类型引用的概念:
1.强引用(StrongReference)
强引用就是指在程序代码之中普遍存在的,比如下面这段代码中的object和str都是强引用:
1
2
|
Object object = new Object(); String str = "hello" ; |
只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。比如下面这段代码:
1
2
3
4
5
6
7
8
9
10
|
public class Main { public static void main(String[] args) { new Main().fun1(); } public void fun1() { Object object = new Object(); Object[] objArr = new Object[ 1000 ]; } } |
当运行至Object[] objArr = new Object[1000];这句时,如果内存不足,JVM会抛出OOM错误也不会回收object指向的对象。不过要注意的是,当fun1运行完之后,object和objArr都已经不存在了,所以它们指向的对象都会被JVM回收。
如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。
比如Vector类的clear方法中就是通过将引用赋值为null来实现清理工作的:
/**
* Removes the element at the specified position in this Vector.
* Shifts any subsequent elements to the left (subtracts one from their
* indices). Returns the element that was removed from the Vector.
*
* @throws ArrayIndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= size()})
* @param index the index of the element to be removed
* @return element that was removed
* @since 1.2
*/
public synchronized E remove(int index) {
modCount++;
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
Object oldValue = elementData[index]; int numMoved = elementCount - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--elementCount] = null; // Let gc do its work return (E)oldValue;
}
2.软引用(SoftReference)
软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中。下面是一个使用示例:
1
2
3
4
5
6
7
8
9
|
import java.lang.ref.SoftReference; public class Main { public static void main(String[] args) { SoftReference<String> sr = new SoftReference<String>( new String( "hello" )); System.out.println(sr.get()); } } |
3.弱引用(WeakReference)
弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。下面是使用示例:
1
2
3
4
5
6
7
8
9
10
11
12
|
import java.lang.ref.WeakReference; public class Main { public static void main(String[] args) { WeakReference<String> sr = new WeakReference<String>( new String( "hello" )); System.out.println(sr.get()); System.gc(); //通知JVM的gc进行垃圾回收 System.out.println(sr.get()); } } |
弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中。
4.虚引用(PhantomReference)
虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。
要注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
1
2
3
4
5
6
7
8
9
10
11
|
import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; public class Main { public static void main(String[] args) { ReferenceQueue<String> queue = new ReferenceQueue<String>(); PhantomReference<String> pr = new PhantomReference<String>( new String( "hello" ), queue); System.out.println(pr.get()); } } |
二.进一步理解软引用和弱引用
对于强引用,我们平时在编写代码时经常会用到。而对于其他三种类型的引用,使用得最多的就是软引用和弱引用,这2种既有相似之处又有区别。它们都是用来描述非必需对象的,但是被软引用关联的对象只有在内存不足时才会被回收,而被弱引用关联的对象在JVM进行垃圾回收时总会被回收。
在SoftReference类中,有三个方法,两个构造方法和一个get方法(WekReference类似):
两个构造方法:
1
2
3
4
5
6
7
8
9
|
public SoftReference(T referent) { super (referent); this .timestamp = clock; } public SoftReference(T referent, ReferenceQueue<? super T> q) { super (referent, q); this .timestamp = clock; } |
get方法用来获取与软引用关联的对象的引用,如果该对象被回收了,则返回null。
在使用软引用和弱引用的时候,我们可以显示地通过System.gc()来通知JVM进行垃圾回收,但是要注意的是,虽然发出了通知,JVM不一定会立刻执行,也就是说这句是无法确保此时JVM一定会进行垃圾回收的。
参考链接:https://blog.csdn.net/fyxxq/article/details/51523870
java的几种引用的更多相关文章
- Java中四种引用:强、软、弱、虚引用
这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...
- Java基础:Java的四种引用
在Java基础:java虚拟机(JVM)中,我们提到了Java的四种引用.包括:强引用,软引用,弱引用,虚引用.这篇博客将详细的讲解一下这四种引用. 1. 强引用 2. 软引用 3. 弱引用 4. 虚 ...
- Java 8 的新特性和Java 的4种引用方式
一.接口的增强 Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法,示例如下: interface Formula { double ca ...
- Java的四种引用方式
一.引用基本概念 从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用.虚引用. 1.强引用(StrongRef ...
- Java的四种引用
1.强引用(StrongReference)强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程 ...
- JAVA的四种引用,强弱软虚用到的场景
1.强引用 最常用的引用类型,如Object object = new Object(),只要强引用存在,GC必定 不回收,即使当前内存空间不足,jAVA虚拟机宁愿抛出OutofMemoryError ...
- java 的几种引用
从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 1.强引用 本章前文介绍的引用实际上都是强引用, ...
- Java虚拟机(五)Java的四种引用级别
1.前言 HotSpot采取了可达性分析算法用来判断对象是否被能被GC,无论是引用计算法还是可达性分析算法都是判断对象是否存在引用来判断对象是否存活.如果reference类型的数据中存储的数值代表的 ...
- 转载:Java的四种引用方式
原文:https://www.cnblogs.com/huajiezh/p/5835618.html Java内存管理分为内存分配和内存回收,都不需要程序员负责,垃圾回收的机制主要是看对象是否有引用指 ...
- Java的四种引用?用到的场景?
在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK 1.2版本开始,把对象的引用分 ...
随机推荐
- Node学习笔记:建立TCP服务器和客户端之间的通信
结构: socket是应用层和传输层的桥梁.(传输层之上的协议所涉及的数据都是在本机处理的,并没进入网络中) 涉及数据: socket所涉及的数据是报文,是明文. 作用: 建立长久链接,供网络上的两个 ...
- drone 1.0 新的定时任务界面&&构建任务支持重启
drone 1.0 的定时任务是一个不错的功能,早期的版本是必须使用cron 表达式的 最近发布的版本支持通过配置就可以了,很方便,只是目前比较简单的,支持小时. 天.周.月.年的模式 环境准备 do ...
- 模拟实现memcpy 与 memmove
模拟实现memcpy 与 memmove 1.str系列的函数只能处理字符串——>必须带有'\0'2.memcpy内存处理函数:不涉及'\0',需要包含头文件 string.h3.source的 ...
- Flume 高可用配置案例+load balance负载均衡+ 案例:日志的采集及汇总
高可用配置案例 (一).failover故障转移 在完成单点的Flume NG搭建后,下面我们搭建一个高可用的Flume NG集群,架构图如下所示: (1)节点分配 Flume的Agent和Colle ...
- Eclipse提交代码到Spark集群上运行
Spark集群master节点: 192.168.168.200 Eclipse运行windows主机: 192.168.168.100 场景: 为了测试在Eclipse上开发的代码在Spa ...
- 文件如何转换成pdf或html格式
1.使用jacob插件 2.使用方法 1)于word.ppt等上传文件转换为PDF格式文件的环境搭建,步骤如下:① 首先电脑要先安装office软件(不可以是WPS软件)② 需要把jacob.dll文 ...
- supervisor的安装部署及集群管理
supervisor的安装部署及集群管理 supervisor官网:http://www.supervisord.org/ 参考链接: http://blog.csdn.net/xyang81/art ...
- 黄聪:WordPress 启用HTTPS设置(转)
HTTPS已经成为网站的一种趋势,得益于数以万计的开发者和百万计的玩家,Wordpress启用HTTPS过程相当简单.下面就把Wordpress启用HTTPS访问的过程记录一下,以供参考. 一. 修改 ...
- PHP 遍历文件夹下的文件以及子文件夹
// 递归的方式实现function my_dir( $dir ){ if ( !is_dir($dir) ) { return 'not dir';die(); } $files = array() ...
- 【springBoot】之快速构建一个web项目
基于maven,首先看pom文件 <parent> <groupId>org.springframework.boot</groupId> <artifact ...