一直知道Java的引用分四类:强引用、软引用、弱引用、虚引用,但仔细想想又觉得领悟不够多,故此总结一下;
首先要分清两个概念,对象可达性、不同类别的引用;
对象可达性针对对象的概念,不同的引用针对引用的概念;
虽然下文描述显示可达性再是引用类型,但实际系统允许时,判断一个对象能否回收,首先要看到它的可达性,如何判断它的可达性,肯定是先判断指向它的那些“引用”;
所以分析时,应该先是看某对象的各个引用,它们的类别,再近而结合对象本身的可达性;

对象达到性

当Java虚拟机(JVM)觉得内存不够用的时候,会触发垃圾回收操作(GC),清除无用的对象,释放内存。
可是如何判断一个对象是否是垃圾呢?
其中的一个方法是计算指向该对象的引用数量。
如果引用数量为0,那么该对象就为垃圾(Thread对象是例外),否则还有用处,不能被回收。但是如果把引用数为0的对象都回收了,还是不能满足内存需求怎么办?Java把引用分为4种类型,垃圾回收器会尝试回收只有弱引用的对象。

达到性性分析算法

在主流的商用程序语言(Java、C#,甚至包括前面提到的古老的Lisp)的主流实现中,都是称通过可达性分析(Reachability Analysis)来判定对象是否存活的。
这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点。
从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。
如图3-1所示,对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。

Java语言中,可作为GC Roots的对象包括下面几种:虚拟机栈(栈帧中的本地变量表)中引用的对象。
方法区中类静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中JNI(即一般说的Native方法)引用的对象。

强可达性对象

在一个线程内,不需要其他引用对象,直接使用,一般新创建的对象针对创建它的线程来说都是强可达的;
任何强可达对象,在它的线程内都不会被回收;
只有它变为不可达对象,才会被回收

软可达对象

当系统内存不足时,系统保证会回收软可达对象;
软引用可用来实现内存敏感的高速缓存.但是具体的行为还是得依赖于JVM。并且多少跟内存回收机制有关,保障很少并且跟具体的JVM发行版本有关。为了缓存的可靠(及其他更多特性),大多数人都会选用像Ehcache而不是用软引用实现自己的缓存。但在一些场合,使用软引用确实可以让代码非常优雅、简洁。

弱可达对象

在垃圾回收期进行垃圾回收时,不管·内存情况,都会回收此类对象;
弱引用不能阻止垃圾回收机制清理他指向的引用。弱引用最常见的使用情景是通过WeakHashMap。它是一种简单地将对象的生命周期跟Map中对象的索引域(key)绑定的方式。只有当WeakHashMap中的Key是强可达,也就是WeakHashMap中的数据域(Data域)的对象,在应用程序的其他地方有别的引用的时候,它里面的值才不会被回收。一旦应用程序中没有其他对WeakHashMap中对象的引用,那么它的所有的key就会变成弱可达,不需要用户的额外干预,所有WeakHashMap中的对象都会被清除。这是一种优雅地防止内存泄露的方式。

虚引用对象

如果一个对象既没有强可达性,也没有软可达性、弱可达性,他已经被终结(finalized),并且有一些虚引用(phantom reference)指向它,那么它就具有虚可达性。

不可达

当一个对象不能通过以上的方式指向,那么这个对象就变得不可达,并因此适合被回收。

4种Java引用

强引用(StrongReference)
我们平时申明变量使用的就是强引用,普通系统99%以上都是强引用。比如,String s = "Hello World"软引用(SoftReference)
类似弱引用,只不过Java虚拟机会尽量让软引用的存活时间长一些,迫不得已才清理。弱引用(WeakReference)
垃圾回收器某个时刻决定回收软可达的对象的时候,会清理软引用,并可选的把引用存放到一个引用队列(ReferenceQueue)。虚引用(PhantomReference)
仅用来处理资源的清理问题,比Object里面的finalize机制更灵活。get方法返回的永远是null,Java虚拟机不负责清理虚引用,但是它会把虚引用放到引用队列里面。

例子

使用HashMap,会报out of memory错误。
public static void main(String[] args) {Map<String, String> list = new HashMap<String, String>();long i = 1;while (i < 100000000L) {list.put(String.valueOf(i),"JDJJDJJJJJJJJJJ%%%%%%%%JJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKJJJJJJ"+ "JJJKKKKKHDDDJDJDJDJDJDJDJDJJDJDJDJDJDJDJJDJDJDJDJJDJDJJJJJJJJJ"+ "JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ"+ "JJJJJJJJJJJJJJJJJJJJJJJJJJJJ");// 测试第一个是否依然存活if (i % 100000 == 0) {System.out.println(list.get(String.valueOf(1)));}i++;}}
public static void main(String[] args) {Map<String, String> list = new WeakHashMap<String, String>();long i = 1;while (i < 100000000L) {list.put(String.valueOf(i),"JDJJDJJJJJJJJJJ%%%%%%%%JJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKJJJJJJ"+ "JJJKKKKKHDDDJDJDJDJDJDJDJDJJDJDJDJDJDJDJJDJDJDJDJJDJDJJJJJJJJJ"+ "JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ"+ "JJJJJJJJJJJJJJJJJJJJJJJJJJJJ");// 测试第一个是否依然存活if (i % 100000 == 0) {System.out.println(list.get(String.valueOf(1)));}i++;}}

老调重弹之Java引用类型相关推荐

  1. 【Java 虚拟机原理】Java 引用类型 ( 强引用 | 软引用 | 弱引用 | 虚引用 | 静态变量 )

    文章目录 一.静态变量 二. Java 引用类型 ( 强.软.弱.虚 ) 一.静态变量 GC Root 对象 : 线程栈 中的 栈帧 中的 局部变量表 中的 引用对象 ; 方法区 中的 静态引用对象 ...

  2. 【Android 内存优化】Java 引用类型 ( 强引用 | 软引用 | 弱引用 | 虚引用 )

    文章目录 一. Java 引用类型 ( 强.软.弱.虚 ) 二. 软引用代码示例 三. 弱引用代码示例 强引用 ( 不回收 ) > 软引用 ( OOM 前回收 ) > 弱引用 ( GC 必 ...

  3. Java引用类型与常量

    Java引用类型与常量 引用数据类型 Java中,引用类型的变量非常类似于C/C++的指针. 引用类型指向一个对象,指向对象的变量是引用变量,这些变量在声明时被指定为一个特定的类型,比如Employe ...

  4. Java引用类型有哪些

    动力节点Java培训最新上线Java实验班,等你来测试自己适不适合学习Java编程哦! Java类型一般有两种,即基本数据类型与引用数据类型.其中,引用数据类型在存储堆中对需要引用的对象进行引用,引用 ...

  5. 深入理解Java引用类型

    深入理解Java引用类型 在Java中类型可分为两大类:值类型与引用类型.值类型就是基本数据类型(如int ,double 等),而引用类型,是指除了基本的变量类型之外的所有类型(如通过 class ...

  6. Java引用类型分类以及详解

    Java引用类型分类以及详解 - Java引用类型概述 在JVM之中再好的算法,也敌不过一个好烂的程序员.一个程序要想写好有两点:按照开发标准进行.请写有用代码. 而对于垃圾的产生与回收的处理之中,要 ...

  7. Java引用类型用法总结(重点)

    Java引用类型 引用数据类型:数组,类(String),接口. class作为成员变量 类作为成员变量时,对它进行赋值的操作,实际上,是赋给它该类的一个对象. Role.java package r ...

  8. java的虚引用_你不可不知的Java引用类型之——虚引用

    定义 虚引用是使用PhantomReference创建的引用,虚引用也称为幽灵引用或者幻影引用,是所有引用类型中最弱的一个.一个对象是否有虚引用的存在,完全不会对其生命周期构成影响,也无法通过虚引用获 ...

  9. java引用类型使用场景_下面有关java的引用类型,说法正确的有?

    发现这道题完全没头绪,就去查了一下,感觉说的比较清楚了. 四种引用类型 JDK1.2 之前,一个对象只有"已被引用"和"未被引用"两种状态,这将无法描述某些特殊 ...

最新文章

  1. C++ queue 详细介绍
  2. linux查看本机所有预设的系统变量,如何设置与查看Linux系统中的环境变量?
  3. UK Biobank专题
  4. python中的@、-、*arg、**kwarg使用方法[探索1]
  5. 拓端tecdat|Nelsen-Siegel—Svensson扩展模型简介
  6. 基于JAVA宠物管理系统的设计与实现
  7. 五类推荐系统算法,非常好使,非常全面
  8. 华为OD机试(JAVA)真题II
  9. Google Chrome Your browser is not compatible with FlexPaper问题解决
  10. 解决Tortoise git没有红色、绿色勾勾的问题
  11. B站粉丝计数器 | ESP32轻松学(Arduino版)
  12. 技术岗的职业规划_技术人员职业规划精选范文
  13. 美国合同法笔记-合同定义
  14. 【算法】深度搜索(DFS) 和 广度搜索(BFS)
  15. Linux是什么 ?
  16. 中班音乐活动 机器人_中班下学期音乐《机器人》活动反思
  17. 重邮大学计算机基础考试试题及答案,重庆邮电大学《大学计算机基础(2015》考试试卷.pdf...
  18. Python——函数练习题
  19. 专治懒癌100年,疗效嗷嗷好!
  20. java 浏览器 pdf_使用iText在浏览器中打开生成的PDF

热门文章

  1. xtrabackup 命令详解
  2. JMeter 接口测试-if控制器
  3. 打孔纸带计算机运行原理
  4. android物理键盘灯控制,Android按键灯流程分析
  5. 单片机胡汉才第四版答案_单片机课后习题答案 胡汉才编
  6. template 的用法
  7. 灰帽子python 读书笔记 1
  8. 外文网站对CMap用法的精辟解释
  9. Kubernetes 学习总结(28)—— Kubernetes 常见问题总结
  10. papi酱视频因违规遭下线整改,你知道原因吗?