引用

Java 虚拟机接管了所有的内存分配与回收工作,极大地减少了程序员的工作量和错误率。GC 在回收内存时,通常采用被称为可达性分析的算法判断一个对象是否可以回收。而在可达性分析中,对象的引用有着决定性的作用。在下图中,GC 从 GC Roots 开始顺着引用链往下寻找对象,发现当前有引用的对象为object 1、object 2、object 3、object 4,而object 5、object 6、object 7虽然互相之间有引用但已经无法从外部引用到。因此,图中 object 1-4 为存活的对象,而 object 5-7 为可回收的对象。

虽然 GC 能够完成垃圾收集工作,但是仍然无法避免 out of memory 。一方面在开发过程中需要注意不再使用的引用设为 null 来释放引用的对象,另一方面也需要从对象引用的角度考虑使用合适的引用类型更好地管理对象内存。

引用的类型

Java 有4种类型的引用:strong(强引用),soft(软引用),weak(弱引用)和 phantom(虚引用)。

强引用:强引用是在 Java 中的普通引用。任何时候我们创建一个新的对象,默认情况下创建一个强引用。例如类的静态变量,从类被初始化之后便已经分配内存,作为强引用对象不能被 GC 回收,需要等待虚拟机退出或类被卸载才能释放引用被 GC 回收。

弱引用:弱引用无法保证对象一定存活于内存中,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。我们可以使用 WeakReference 类来实现弱引用。

软引用:软引用比弱引用稍强一点,垃圾收集发生时弱引用一定会被回收,而软引用会请求 GC 保留自己除非没有其他选择,可以理解为只在将要发生内存溢出时 GC 才会回收软引用。我们可以使用 SoftReference 类来实现软引用。

虚引用:一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被 GC 回收时收到一个系统通知。我们可以使用 PhantomReference 类来实现虚引用。当 GC 准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。开发者可以通过判断引用队列中是否包含对象来判断对象是否即将被回收,可以在回收之前做些处理。

引用队列:如果引用关联了引用队列,则 GC 回收对象内存的时候会把引用加入到引用队列中。当引用队列中包含引用时,意味着引用指向的堆内存中的对象被回收。

引用的应用

构建缓存

使用软引用可以用于创建 Java 本地高速缓存,只要内存仍然够用缓存就不会被删除,而一旦内存紧张即将溢出时,GC 会删除部分缓存释放内存。例如,创建比较耗时影响性能的数据对象、一段时间内可以重复使用的资源、不常变化的数据等,都可以使用软引用构建缓存,既能保证读取性能,又不会导致内存溢出。

WeakHashMap

WeakHashMap 是以弱引用键实现的哈希表。当 WeakHashMap 中的键不再被强引用使用时,GC 下次回收垃圾时将回收此键。WeakHashMap 中的键被回收后,哈希表的条目也会被 GC 回收。因此,WeakHashMap 可以用于临时存储一些不需要长时间使用的对象,可以有效避免内存溢出。

总结

Java 开发中最常用的引用是强引用,通过new创建对象得到强引用。强引用会阻止 GC 释放对象内存,长时间运行容易导致内存溢出。在开发中,对于强引用变量在使用完毕后应把值设置为 null 来帮助 GC 进行垃圾回收。在 Java 中还有另外三种引用类型,弱引用、软引用和虚引用。弱引用和软引用可以用于构建缓存和避免内存泄露,虚引用可以用于获知对象将被回收的通知并进行处理。

四种引用类型的对比如下:

原文地址:关于Java引用,你必须知道这些

关于Java引用,你必须知道这些的更多相关文章

  1. Java引用总结--StrongReference、SoftReference、WeakReference、PhantomReference

    Java引用总结--StrongReference.SoftReference.WeakReference.PhantomReference 1 Java引用介绍 Java从1.2版本开始引入了4种引 ...

  2. 4种Java引用浅解

    近期研究Java Cache实现,发现使用到了软引用(SoftReference),不太理解,查阅了JDK文档.代码以及几篇文章.做个小结,如有错误,欢迎指正. 之所以想学习一下Java的几种引用类型 ...

  3. Java引用类型变量

    Java引用类型变量 1.编译时类型:由声明该变量时使用的类型决定 2.执行时类型:由实际赋给该变量的对象决定    类型不一致的假设编译时类型和执行,可能会出现多态性 版权声明:本文博主原创文章.博 ...

  4. Java引用变量的类型

    Java引用变量的类型 1.编译时类型:由声明该变量时使用的类型决定 2.运行时类型:由实际赋给该变量的对象决定    如果编译时类型和运行时类型不一致,就可能出现多态性

  5. Java引用详解-StrongReference SoftReference WeakReference PhantomReference

    1 Java引用介绍 Java从1.2版本开始引入了4种引用,这4种引用的级别由高到低依次为:    强引用  >  软引用  >  弱引用  >  虚引用 ⑴强引用(StrongR ...

  6. 浅谈Java引用和Threadlocal的那些事

      这篇文章主要介绍了Java引用和Threadlocal的那些事,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 1 背景 某一天在某一个群里面的某个群友突然提出了一个问 ...

  7. java引用知识

    最近从新拜读<深入理解Java虚拟机:JVM高级特性与最佳实践>这本书,看到有关引用的相关知识,以前没有好的习惯,这次看完在博客上记录下 引用:如果reference类型中的数据存储的数值 ...

  8. Java引用与C语言指针的区别

    1.现象 指针在运行时可以改变其所指向的值(地址)即指向其它变量,而引用一旦和某个对象绑定后就不能再改变,总是指向最初的对象. 2.编译 程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变 ...

  9. Java引用的分类

    Java引用分为强引用.软引用.弱引用和虚引用. 强引用就是指在程序代码中普遍存在的,类似“Object obj = new Object()”这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被 ...

  10. 你不知道的Java引用

    什么是引用   引用就是保存着一块地址(门牌号)的对象,就像C语言的指针那样,引用可以传递某个数据的地址,如果我们想拿到某一条数据,就要先找到他的地址,然后告诉计算机我去拿这个地址的数据,最后计算机就 ...

随机推荐

  1. 盘点MySQL中比较实用的函数

    之前小编在工作中遇到一些处理数据的问题,例如完成日期格式化,获取几天后的时间,生成指定格式的编码等问题,这时候小编经常会写一大堆逻辑代码来进行处理,还自己感觉自己很流弊的样子,后来却发现同事遇到相同的 ...

  2. Lua table(表)

    table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数组.字典等. Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil. Lua ta ...

  3. Asp.Net Core 企业微信静默授权

    企业微信接口文档 1.构造授权网页链接 2.回调获取到 Code 通过code+access_token去请求用户信息 3.获取access_token 调试准备工作 -->内网穿透+域名 推荐 ...

  4. Word rings

    Word rings 题目描述 这道题就是想求出所有的环,然后在所有环中比较出环串的平均长度最长的那一个,然后就输出平均长度最长的,如果在一个点当中的样例中没有环的话我们就应该输出"No S ...

  5. 027 01 Android 零基础入门 01 Java基础语法 03 Java运算符 07 逻辑“与”运算符

    027 01 Android 零基础入门 01 Java基础语法 03 Java运算符 07 逻辑"与"运算符 本文知识点:Java中的逻辑"与"运算符 逻辑运 ...

  6. [源码阅读] 阿里SOFA服务注册中心MetaServer(1)

    [源码阅读] 阿里SOFA服务注册中心MetaServer(1) 目录 [源码阅读] 阿里SOFA服务注册中心MetaServer(1) 0x00 摘要 0x01 服务注册中心 1.1 服务注册中心简 ...

  7. 在Windows7系统中设置虚拟内存大小

    当我们的电脑物理内存空间不够用时,操作系统就会自动从硬盘空间上分出一块空间来当内存使用,这就是虚拟内存.可以说虚拟内存是物理内存的补充,是备用的物理内存.一般来说,如果电脑里的程序不多,占用内存资源不 ...

  8. devops-jenkins-Pipeline实战

    1) 配置gitlab的分支项目 点击红色标记的创建 project 项目 点击Create project创建Pipeline-demo项目 项目创建完成,然后我们创建一个Add README 然后 ...

  9. 热力图 vue 项目中使用热力图插件 “heatmap.js”(保姆式教程)

    我现在写的这项目是用CDN引入 heatmap.js, 可根据自己项目情况使用哪种方式引入插件. 官网地址 "https://www.patrick-wied.at/static/heatm ...

  10. 多测师讲解自动化测试 _如何解决验证码的问题_高级讲师肖sir

    自动化测试如何解决验证码的问题对于web应用来说,大部分的系统在用户登录时都要求用户输入验证码,验证码的类型的很多,有字母数字的,有汉字的,甚至还要用户输入一条算术题的答案的,对于系统来说使用验证码可 ...