博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java四种引用类型
阅读量:6962 次
发布时间:2019-06-27

本文共 4691 字,大约阅读时间需要 15 分钟。

Java四种引用类型

在java中,类型就分为两种,基本类型和引用类型或自定义类型。

引用类型又分为四种:

  1. 强引用 StrongReference

  2. 软引用 SoftReference

  3. 若引用 WeakReference

  4. 虚引用 PhantomReference

划分这些类型的目的是:是为了更灵活的管理对象的生命周期,让垃圾器在最合适的时间适合回收对象,常见使用的场景是在缓存的实现,比如elasticsearch在载入数据到缓存时,可以选择SoftReference作为缓存的生命周期,在对象池组件common-pool中也利用到SoftReference管理对象池的对象生命周期。虽然,我们在实际业务中很少有用到这些知识,但是很有必要了解到这些,去帮助我们去做些程序性能优化。

强引用

强引用就是直接引用对象比如下面这样,我们在编写程序时,用到的大多都是强引用

StringBuffer b1 = new StringBuffer("hello world");

强引用对象,当垃圾回收进行时,不会被回收,及时通过b1 = null;释放引用,在资源充足时,也不会被垃圾回收立刻回收。如果内存吃紧,Java虚拟机会抛出OutOfMemoryError错误,使程序异常终止,不会靠随意回收具有强引用的对象来解决内存不足的问题。

软引用

SoftReference
softReference = new SoftReference
(new StringBuffer("hello world"));System.gc();System.out.print(softReference.get()); // 只有当内存吃紧时,发生gc后,会报Exception in thread "main" java.lang.NullPointerException,

软引用的生命周期会比强引用弱点,在内存空间足够时,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。

它也经常和ReferenceQueue配合使用,如果gc在回收掉引用对象后,会把保存引用对象的softReference送入队列,这时可以通过下面这行代码判断是否被回收。

// 创建softReference并提供给注册队列ReferenceQueue
referenceQueue = new ReferenceQueue
();SoftReference
softReference = new SoftReference
(new StringBuffer("hello world"),referenceQueue);// 判断入队列来判断是否被回收,或直接判断softReference.get() == nullsoftReference.get() == null || softReference.enqueue()

另外也可以手动清除这些保存引用对象的reference对象

Reference ref;while ((ref = referenceQueue.poll()) != null) {    // poll出即清除,也不必手动清除,等待gc清除}

使用案列:common-pool2的SoftReferenceObjectPool,用于实现一种可以随着需要而增长的池对象管理,当gc时可以清除空闲的实例。

下面是common-pool2的部分代码,具体可以参照其里面的SoftReferenceObjectPool

@Overridepublic synchronized void addObject() throws Exception {    assertOpen();    if (factory == null) {        throw new IllegalStateException(                "Cannot add objects without a factory.");    }    T obj = factory.makeObject().getObject();    createCount++;    // Create and register with the queue    PooledSoftReference
ref = new PooledSoftReference
( new SoftReference
(obj, refQueue)); allReferences.add(ref); boolean success = true; if (!factory.validateObject(ref)) { success = false; } else { factory.passivateObject(ref); } boolean shouldDestroy = !success; if (success) { idleReferences.add(ref); notifyAll(); // numActive has changed } if (shouldDestroy) { try { destroy(ref); } catch (Exception e) { // ignored } } @Override public synchronized void returnObject(T obj) throws Exception { boolean success = !isClosed(); final PooledSoftReference
ref = findReference(obj); if (ref == null) { throw new IllegalStateException( "Returned object not currently part of this pool"); } if (factory != null) { if (!factory.validateObject(ref)) { success = false; } else { try { factory.passivateObject(ref); } catch (Exception e) { success = false; } } } boolean shouldDestroy = !success; numActive--; if (success) { // Deallocate and add to the idle instance pool ref.deallocate(); idleReferences.add(ref); } notifyAll(); // numActive has changed if (shouldDestroy && factory != null) { try { destroy(ref); } catch (Exception e) { // ignored } } }

弱引用

WeakReference
weakReference = new WeakReference
(new StringBuffer("hello world"));WeakReference
weakReference2 = new WeakReference
(new StringBuffer("hello world"));System.out.print(weakReference.get()); // hello worldStringBuffer buffer = weakReference2.get();System.gc();System.out.print(weakReference.get()); // Exception in thread "main" java.lang.NullPointerExceptionSystem.out.print(weakReference2.get()); // hello world

弱引用会在发生gc时,没有对象在去引用时会被立刻被回收,不管内存是否充裕。

使用案列:WeakHashMap

虚引用

ReferenceQueue
stringBufferReferenceQueue = new ReferenceQueue
();PhantomReference
phantomReference = new PhantomReference
(new StringBuffer("hello world"), stringBufferReferenceQueue);System.out.print(phantomReference.get());Exception in thread "main" java.lang.NullPointerException

虚引用,不顾是否被垃圾回收,都不可以拿到真正的引用对象。一般用法是

程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

具体Demo代码请参照:ReferenceDemo

转载地址:http://qhwsl.baihongyu.com/

你可能感兴趣的文章
MySQL数据库入门——多实例配置
查看>>
ACtiiveMQ安装 Ubuntu
查看>>
四色原则
查看>>
1.sql数据处理问题
查看>>
企业管理:如何规范员工上网行为,提高员工工作效率
查看>>
LINUX创建、删除用户和用户组;修改密码
查看>>
深入理解乐观锁与悲观锁
查看>>
CocoaPods的使用
查看>>
find命令详解
查看>>
变频电源内部IGBT模块的作用是什么样的
查看>>
手机PDF文件怎么压缩得更小,PDF文件如何压缩?
查看>>
超声波清洗机对人体有辐射,有伤害吗?
查看>>
区块链成多地政府工作报告新热词
查看>>
论职场沟通的重要性
查看>>
velocity模板中后台返回html,前端无法跳转页面
查看>>
AJPFX:如何保证对象唯一性呢?
查看>>
天禹智控--现场标准气体如何使用?
查看>>
CSS3:border-radius隐藏的威力
查看>>
springMVC 返回类型选择 以及 SpringMVC中model,modelMap
查看>>
存储型XSS进阶 [猜测规则,利用Flash addCallback构造XSS]
查看>>