面试官:详细谈谈Java对象的4种引用方式

作者:yes的练级攻略 时间:2022-09-19 04:52:20 

前言

我们知道在Java中除了基础的数据类型以外,其它的都为引用类型。

而Java根据其生命周期的长短将引用类型又分为强引用、软引用、弱引用、幻象引用 。

正常情况下我们平时基本上我们只用到强引用类型,而其他的引用类型我们也就在面试中,或者平日阅读类库或其他框架源码的时候才能见到。

1.强引用

我们平日里面的用到的new了一个对象就是强引用,例如 Object obj = new Object();当JVM的内存空间不足时,宁愿抛出OutOfMemoryError使得程序异常终止也不愿意回收具有强引用的存活着的对象!

记住是存活着,不可能是你new一个对象就永远不会被GC回收。当一个普通对象没有其他引用关系,只要超过了引用的作用域或者显示的将引用赋值为null时,你的对象就表明不是存活着,这样就会可以被GC回收了。当然回收的时间是不一定的具体得看GC回收策略。

2.软引用

软引用的生命周期比强引用短一些。软引用是通过SoftReference类实现的。


Object obj = new Object();
SoftReference softObj = new SoftReference(obj);
obj = null; //去除强引用

这样就是一个简单的软引用使用方法。通过get()方法获取对象。当JVM认为内存空间不足时,就回去试图回收软引用指向的对象,也就是说在JVM抛出OutOfMemoryError之前,会去清理软引用对象。软引用可以与引用队列(ReferenceQueue)联合使用。


Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference softObj = new SoftReference(obj,queue);
obj = null; //去除强引用

当softObj软引用的obj被GC回收之后,softObj 对象就会被塞到queue中,之后我们可以通过这个队列的poll()来检查你关心的对象是否被回收了,如果队列为空,就返回一个null。反之就返回软引用对象也就是softObj。

软引用一般用来实现内存敏感的缓存,如果有空闲内存就可以保留缓存,当内存不足时就清理掉,这样就保证使用缓存的同时不会耗尽内存。例如图片缓存框架中缓存图片就是通过软引用的。

3.弱引用

弱引用是通过WeakReference类实现的,它的生命周期比软引用还要短,也是通过get()方法获取对象。


Object obj = new Object();
WeakReference<Object> weakObj = new WeakReference<Object>(obj);
obj = null; //去除强引用

在GC的时候,不管内存空间足不足都会回收这个对象,同样也可以配合ReferenceQueue 使用,也同样适用于内存敏感的缓存。ThreadLocal中的key就用到了弱引用。

4.幻象引用

也称虚引用,是通过PhantomReference类实现的。任何时候可能被GC回收,就像没有引用一样。


Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
PhantomReference<Object> phantomObj = new PhantomReference<Object>(obj , queue);
obj = null; //去除强引用

无法通过虚引用访问对象的任何属性或者函数。那就要问了要它有什么用?虚引用仅仅只是提供了一种确保对象被finalize以后来做某些事情的机制。比如说这个对象被回收之后发一个系统通知啊啥的。虚引用是必须配合ReferenceQueue 使用的,具体使用方法和上面提到软引用的一样。主要用来跟踪对象被垃圾回收的活动。

来源:https://juejin.im/post/5cd386be51882511282b8746

标签:java,对象,引用
0
投稿

猜你喜欢

  • JAVA 字符串加密、密码加密实现方法

    2023-11-28 04:08:09
  • C#复制数组的两种方式及效率比较

    2023-07-15 04:19:12
  • Java线程创建的四种方式总结

    2023-10-29 19:36:03
  • Java的Spring框架下的AOP编程模式示例

    2023-11-02 00:52:25
  • Java手动实现Redis的LRU缓存机制

    2023-07-31 12:51:30
  • Spring Security实现用户名密码登录详解

    2021-05-24 14:32:36
  • Javassist之一秒理解java动态编程

    2023-11-09 09:36:33
  • Android仿百度图片查看功能

    2023-09-26 07:50:24
  • Java代码实现酒店管理系统

    2023-08-13 13:09:23
  • MyBatis插入Insert、InsertSelective的区别及使用心得

    2023-08-25 04:34:28
  • 关于C#中的Invoke示例详解

    2023-06-20 10:17:14
  • Java集合框架之List ArrayList LinkedList使用详解刨析

    2022-04-24 13:43:43
  • 细谈java同步之JMM(Java Memory Model)

    2023-11-23 13:09:33
  • Java类中this关键字与static关键字的用法解析

    2023-11-09 22:45:19
  • java设计模式之工厂模式实例详解

    2023-11-24 23:35:12
  • 基于C语言实现井字棋游戏

    2023-06-28 21:23:18
  • 详解SpringCloud Ribbon 负载均衡通过服务器名无法连接的神坑

    2021-06-01 07:28:41
  • Java设计模式之备忘录模式(Memento模式)介绍

    2023-08-23 14:26:42
  • 六款值得推荐的android(安卓)开源框架简介

    2023-06-24 01:46:54
  • 关于java入门与java开发环境配置详细教程

    2023-11-24 14:21:44
  • asp之家 软件编程 m.aspxhome.com