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

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

  hot3.png

一. 引用类型

java引用类型共有以下四种:

1.强引用

所谓强引用("Strong" Reference),就是我们最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾收集器不会碰这种对象。对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为 null,就是可以被垃圾收集的了,当然具体回收时机还是要看垃圾收集策略。

2.软引用

软引用(SoftReference),是一种相对强引用弱化一些的引用,可以让对象豁免一些垃圾收集,只有当 JVM 认为内存不足时,才会去试图回收软引用指向的对象。JVM 会确保在抛出 OutOfMemoryError 之前,清理软引用指向的对象。软引用通常用来实现内存敏感的缓存,如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存。

3.弱引用

弱引用(WeakReference)并不能使对象豁免垃圾收集,仅仅是提供一种访问在弱引用状态下对象的途径。这就可以用来构建一种没有特定约束的关系,比如,维护一种非强制性的映射关系,如果试图获取时对象还在,就使用它,否则重现实例化。它同样是很多缓存实现的选择。

4.幻象引用

对于幻象引用,有时候也翻译成虚引用,你不能通过它访问对象。幻象引用仅仅是提供了一种确保对象被 finalize 以后,做某些事情的机制,比如,通常用来做所谓的 Post-Mortem 清理机制,我在专栏上一讲中介绍的 Java 平台自身 Cleaner 机制等,也有人利用幻象引用监控对象的创建和销毁。

java之所以会有不同的引用类型,是由于对象的引用状态会有垃圾回收产生影响,如对于一些缓存对象,可以使用软引用来构建,当内存充足时,垃圾回收状态与强引用类型一致;当内存不足时,会回收这些对象的内存。

二.使用

1.弱引用的使用

平时,我们使用Object obj = new Object()创建对象时,创建的就是一个强引用。对于软引用与弱引用,jdk提供了相关的类,列出如下:

SoftReference
SoftReference(T) SoftReference(T, ReferenceQueue
) T get() ···WeakReference
WeakReference(T) WeakReference(T, ReferenceQueue
) T get() ···

可以看到,两个类中,主要使用的是构造方法与get方法,使用示例如下:

//创建一个弱引用,引用的对象是new Object()WeakReference reference = new WeakReference<>(new Object());//使用get方法获取引用的对象Object object = reference.get();

2.引用队列的使用

谈到各种引用的编程,就必然要提到引用队列。我们在创建各种引用并关联到响应对象时,可以选择是否需要关联引用队列,JVM 会在特定时机将引用 enqueue 到队列里,我们可以从队列里获取引用(remove 方法在这里实际是有获取的意思)进行相关后续逻辑。尤其是幻象引用,get 方法只返回 null,如果再不指定引用队列,基本就没有意义了。看看下面的示例代码。利用引用队列,我们可以在对象处于相应状态时(对于幻象引用,被 finalize 了,处于幻象可达状态),执行后期处理逻辑。

Object counter = new Object();ReferenceQueue refQueue = new ReferenceQueue<>();PhantomReference p = new PhantomReference<>(counter, refQueue);counter = null;System.gc();try {    // Remove 是一个阻塞方法,可以指定 timeout,或者选择一直阻塞    Reference ref = refQueue.remove(1000L);    if (ref != null) {        // do something    }} catch (InterruptedException e) {    // Handle it}

三.对象可达性判断

jvm在进行垃圾回收时,决定对象是否可以被清除,会判断该对象是否可达,若对象不可达,则清除。

java通过可达性分析来判断对象是否存活。基本思想是通过一系列称为“GC roots”的对象作为起始点,可以作为根节点的是:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象

转载于:https://my.oschina.net/funcy/blog/1921174

你可能感兴趣的文章
3·15曝光丨智能机器人一年拨打40亿个骚扰电话,6亿人信息已遭泄露!
查看>>
ArchSummit深圳2016大会7折售票最后一周
查看>>
2019年React学习路线图
查看>>
Google Docs API正式可用,可自动化文档任务和内容管理
查看>>
全面了解大数据“三驾马车”的开源实现
查看>>
GitHub宣布推出Electron 1.0和Devtron,并将提供无限制的私有代码库
查看>>
人工智能白热化,运维脱帽“背锅侠”
查看>>
Android中使PopupWindow显示在指定控件的上下左右!
查看>>
html中ul标签的优化
查看>>
Kurento安装与入门05——One to many video call
查看>>
[deviceone开发]-cnodejs论坛移动端App
查看>>
智能指针shared_ptr(effective modern c++笔记)
查看>>
Failed to validate a newly established connection异常
查看>>
关联对象 AssociatedObject 完全解析
查看>>
Windows下80端口被pid为4的System进程占用解决方法
查看>>
POST 后台404错误
查看>>
Ubuntu 解压zip文件名乱码问题解决
查看>>
动态规划
查看>>
Hibernate的延迟加载
查看>>
IE中input标签密码框与文本框宽度不一样问题
查看>>