为了更灵活的控制对象的生命周期,在JDK1.2之后,引用被划分为(引用的级别和强度由高到低)强引用、软引用、弱引用、虚引用四种类型,每种类型有不同的生命周期,它们不同的地方就在于垃圾回收器对待它们会使用不同的处理方式。
在Java中,垃圾回收器线程一直在默默的努力工作着,但你却无法在代码中对其进行控制。无法要求垃圾回收器在精确的时间点对某些对象进行回收。有了这些引用类型之后,可以一定程度上增加对垃圾回收的粒度把控,可以让垃圾回收器在更合适的时机回收掉那些可以被回收掉的对象,而并不仅仅是只回收不再使用的对象。

1、强引用:使用最普遍的引用,一般情况下,垃圾回收器绝对不会回收它。当内存不足时,抛出OOM。
如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。

package reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference; public class Reference { public static void main(String[] args) {
// 强引用
Object object = new Object();
Object[] objArr = new
Object[Integer.MAX_VALUE];//报错:java.lang.OutOfMemoryError
object = null;
objArr = null; } }

2、软引用:内存空间足够,垃圾回收器不会回收它。反之,则回收。适用于缓存,而且不会OOM。

软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。
对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中。

package reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference; public class Reference { public static void main(String[] args) { // 软引用
Obj obj = new Obj();
SoftReference<Obj> sr = new SoftReference<Obj>(obj);
obj = null;
System.out.println(sr.get());//reference.Obj@7852e922 } }

3、弱引用:只有当垃圾回收器扫描到弱引用指向的对象时,才会回收它。生命周期比软引用更短。
弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。
弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。所以被软引用关联的对象只有在内存不足时才会被回收,而被弱引用关联的对象在JVM进行垃圾回收时总会被回收。

package reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference; public class Reference { public static void main(String[] args) { //弱引用
WeakReference<String> ss = new WeakReference<String>(new String("hello"));
System.out.println(ss.get());//hello
System.gc(); //通知JVM的gc进行垃圾回收
System.out.println(ss.get());//null } }

4、虚引用:在任何时候都可能被垃圾回收器回收,必须与引用队列关联使用。

虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收的活动。
虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

package reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference; public class Reference { 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());//null
} }

参考:
Java:强引用,软引用,弱引用和虚引用

【Java语言特性学习之三】Java4种对象引用的更多相关文章

  1. 【Java语言特性学习之一】设计模式

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于 ...

  2. 【Java语言特性学习之二】反射

    一.概念java加载class文件分两种情况:(1)类型是编译器已知的,这种文件的.class文件在编译的时候,编译器会把.class文件打开(不加载)检查,称为Run- Time Type Iden ...

  3. 【Java语言特性学习之六】扩展知识点

    一.SPI机制 二.注解处理机制 三.java native关键字 https://www.cnblogs.com/KingIceMou/p/7239668.html

  4. 【Java语言特性学习之四】常用集合

    java中常见的数据结构

  5. 【Java语言特性学习之五】版本差异新特性

  6. [原]Java修炼 之 基础篇(一)Java语言特性

    学习软件开发,首先要选择的就是选择需要采用的编程语言,考虑语言本身的优缺点和实际需求,综合评价之后选择相关的语言进行系统开发.本篇博客开始就从近年来比较流行的Java开始为大家讲起. 背景 1995年 ...

  7. Java 语言特性

    介绍以下几种语言特性: Java5的特性 1.静态引用 2.可变参数 3.自动装箱和拆箱  包装类的缓存设计 4.枚举 一.静态引用(语法糖,不推荐使用,了解一下即可) 先看看普通的引用,就是impo ...

  8. Java语言特性

    Java的语言特性: 1.语法相对简单 2.面向对象 3.分布性 4.可移植性 5.安全性 6.健壮性 7.解释性 8.多线程 9.动态性与并发性 Java中的面向对象编程: 面向对象程序设计(Obj ...

  9. java语言特性概述

    一.前言 我们都知道java是面向对象的编程,其中四个基本特性:抽象.封装.继承.多态.这四个特性,概括起来可以这么理解,抽象.封装.继承是多态的基础,多态是抽象.封装.继承的表现. 二. JAVA ...

随机推荐

  1. node环境下多种方式“get数据解析”

    1.自己写 const http = require('http'); http.createServer(function(req,res){ var get = {}; if(req.url.in ...

  2. php使用inotify扩展监控文件或目录的变化

    一.安装inotify扩展 1.下载inotify扩展源码 https://pecl.php.net/package/inotify 对于php7以上版本,请下载 inotify-2.0.0.tgz. ...

  3. Netty - 粘包和半包(下)

    上一篇介绍了粘包和半包及其通用的解决方案,今天重点来看一下 Netty 是如何实现封装成帧(Framing)方案的. 解码核心流程 之前介绍过三种解码器FixedLengthFrameDecoder. ...

  4. 解决No 'Access-Control-Allow-Origin' header is present on the requested resource.跨域问题

    跨域错误 错误原因 解决方法在后台写一个过滤器过滤器来改写请求头头 CorsFilter.java public class CorsFilter implements Filter { @Overr ...

  5. C# convert between Image and Base64string

    static void ImageMSDemo(string picPath) { byte[] imageArray = System.IO.File.ReadAllBytes(picPath); ...

  6. 苹果 iOS13.2.2 正式版修复闷杀后台问题了?别担心,PerfDog 帮你来检测!

    导语 苹果于上周推送了iOS 13.2版本,带来了用户备受期待的图像处理系统深度融合(Deep Fusion),新增70多个表情.HomeKit安全视频.Siri隐私设置和支持AirPods Pro等 ...

  7. C#如何将DataTable中的列名复制到另一个DataTable

    C#如何将DataTable中的列名复制到另一个DataTable? 仅复制列名,不复制列下的数据: var newDt = new DataTable(); newDt = oldDataTable ...

  8. DDCTF 2019 部分WP

    WEB 滴~ http://117.51.150.246/index.php?jpg=TmpZMlF6WXhOamN5UlRaQk56QTJOdz09 观察链接可发现jpg的值是文件名转hex再bas ...

  9. 为Dynamics CRM注释的图片附件做个预览功能

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复163或者20151017可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! Dynamics CRM中注释可 ...

  10. [b0001] 伪分布式 hadoop 2.6.4

    说明: 任务:搭建Hadoop伪分布式版本. 目的:快速搭建一个学习环境,跳过这一环境,快速进入状态,使用Hadoop一些组件做些任务 没有选择2.7,觉得bug比较多,不稳定. 选择伪分布式简单快速 ...