JAVA 四种引用类型

强引用 在 Java 中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到 JVM 也不会回收。因此强引用是造成 Java 内存泄漏的主要原因之一。

软引用 软引用需要用 SoftReference类来实现,对于只有软引用的对象来说,当系统内存足够时它不会被回收,当系统内存空间不足时它会被回收。软引用通常用在对内存敏感的程序中。

弱引用 弱引用需要用 WeakReference类来实现,它比软引用的生存期更短,对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管 JVM的内存空间是否足够,总会回收该对象占用的内存。

虚引用 虚引用需要 PhantomReference 类来实现,它不能单独使用,必须和引用队列联合使用。虚引用的主要作用是跟踪对象被垃圾回收的状态。

垃圾回收器

我们常用的垃圾回收器是 OracleJDK 中自带的 HotSpot 虚拟机。HotSpot 中使用的垃圾收集器主要包括 7 个:Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS 和 G1(Garbage First)收集器。

Serial 垃圾收集器(单线程、复制算法)

Serial 收集器属于最早期的垃圾收集器,也是 JDK 1.3 版本之前唯一的垃圾收集器。它是单线程运行的垃圾收集器,其单线程是指在进行垃圾回收时所有的工作线程必须暂停,直到垃圾回收结束为止。

Serial 收集器的特点是简单和高效,并且本身的运行对内存要求不高,因此它在客户端模式下使用的比较多。

ParNew 垃圾收集器(Serial+多线程)

ParNew 收集器实际上是 Serial 收集器的多线程并行版本

Parallel Scavenge 收集器(多线程复制算法、高效)

Parallel Scavenge 收集器和 ParNew 收集器类似,它也是一个并行运行的垃圾回收器;不同的是,该收集器关注的侧重点是实现一个可以控制的吞吐量。而这个吞吐量计算的也很奇怪,它的计算公式是:用户运行代码的时间 / (用户运行代码的时间 + 垃圾回收执行的时间)。比如用户运行的时间是 8 分钟,垃圾回收运行的时间是 2 分钟,那么吞吐量就是 80%。Parallel Scavenge 收集器追求的目标就是将这个吞吐量的值,控制在一定的范围内。

Parallel Scavenge 收集器有两个重要的参数:

  • -XX:MaxGCPauseMillis 参数:它是用来控制垃圾回收的最大停顿时间;
  • -XX:GCTimeRatio 参数:它是用来直接设置吞吐量的值的。

Serial Old 收集器(单线程标记整理算法 )

Serial Old 收集器为 Serial 收集器的老年代版本。

Parallel Old 收集器(多线程标记整理算法)

Parallel Old 收集器是 Parallel Scavenge 收集器的老年代版本。

CMS 收集器(多线程标记清除算法)

CMS(Concurrent Mark Sweep)收集器与以吞吐量为目标的 Parallel Scavenge 收集器不同,它强调的是提供最短的停顿时间,因此可能会牺牲一定的吞吐量。它主要应用在 Java Web 项目中,它满足了系统需要短时间停顿的要求,以此来提高用户的交互体验。

CMS 收集器是基于标记-清除算法实现的,我们之前有讲过关于标记-清除的算法,这里简单地回顾一下。标记-清除的算法是由标记阶段和清除阶段构成的,标记阶段会给所有的存活对象做上标记;而清除阶段会把被标记为死亡的对象进行回收,而死亡对象的判断是通过引用计数法或者是目前主流的可达性分析算法实现的。但是 CMS 的实现稍微复杂一些,它的整个过程可以分为四个阶段:

  • 初始标记(CMS initial mark)
  • 并发标记(CMS concurrent mark)
  • 重新标记(CMS remark)
  • 并发清除(CMS concurrent sweep)

首先,初始标记阶段的执行时间很短,它只是标记一下 CG Roots 的关联对象;并发阶段是从 GC Roots 关联的对象进行遍历判断并标识死亡对象,这个过程比较慢,但不需要停止用户线程,用户的线程可以和垃圾收集线程并发执行;而重新标记阶段则是为了判断并标记,刚刚并发阶段用户继续运行的那一部分对象,所以此阶段的执行时间也比较短;最后是并发清除阶段,也就是清除上面标记的死亡对象,由于 CMS 使用的是标记-清除算法,而非标记-整理算法,因此无须移动存活的对象,这个阶段垃圾收集线程也可以和用户线程并发执行。

CMS 的整个执行过程中只有执行时间很短的初始标记和重新标记需要 Stop The World(全局停顿)的,执行过程如下图所示:

因为 CMS 是一款基于标记清除算法实现的垃圾收集器,因此会在收集时产生大量的空间碎片,为了解决这个问题,CMS 收集器提供了一个 -XX:+UseCMS-CompactAtFullCollection 的参数(默认是开启的,此参数从 JDK9 开始废弃),用于在 CMS 收集器进行 Full GC 时开启内存碎片的合并和整理。

但又因为碎片整理的过程必须移动存活的对象,所以它和用户线程是无法并发执行的,为了解决这个问题 CMS 收集器又提供了另外一个参数 -XX:CMSFullGCsBefore-Compaction,用于规定多少次(根据此参数的值决定)之后再进行一次碎片整理。

G1 收集器

Garbage First(简称 G1)收集器是历史发展的产物,也是一款更先进的垃圾收集器,主要面向服务端应用的垃圾收集器。它将内存划分为多个 Region 分区,回收时则以分区为单位进行回收,这样它就可以用相对较少的时间优先回收包含垃圾最多区块。从 JDK 9 之后也成了官方默认的垃圾收集器,官方也推荐使用 G1 来代替选择 CMS 收集器。

JAVA 四种引用类型和垃圾回收器相关推荐

  1. Java 四种引用类型完全解析

    前言 很早就听说有这些引用,从来没用过,最近看源码发现,内部用到的地方挺多,就看了一下相关的文档. 强引用,软引用,弱引用,虚弱引用四种引用类型来方便来管理对象的生命周期. 简单比喻: 1.保洁(GC ...

  2. Java四种引用类型

    文章目录 引用类型简介 对象可达性判断 GC Roots对象 可达性判断 可达性状态类型 可达性判断规则 状态转换 Reference 类定义 状态变化 四种引用类型实现 强引用FinalRefere ...

  3. Java 四种引用类型:强引用、软引用、弱引用、虚引用

    以前学习强软弱虚引用的时候,只是走马观花看看博客,并没有自己写代码去实践.去证明,导致每次看完后,过不了多久就忘了,后来下定决心,一定要自己敲敲代码,这样才能让印象更加深刻,古人云:纸上得来终觉浅,绝 ...

  4. 【Java 引用】Java 四种引用类型

    四种引用类型 一.引用 & 对象 二.四种引用类型 1. 强引用 2. 软引用 3. 弱引用 4. 虚引用 三.引用队列 一.引用 & 对象 Java 声明除基本数据类型外的类型,方式 ...

  5. java ref 应用类型_Java四种引用类型

    Java四种引用类型 在java中,类型就分为两种,基本类型和引用类型或自定义类型. 引用类型又分为四种: 强引用 StrongReference 软引用 SoftReference 若引用 Weak ...

  6. JAVA的四种引用类型的作用——强引用、软引用、弱引用、虚引用

    Java四种引用类型,按照引用类型的强弱顺序分别是 强引用 软引用 弱引用 虚引用 背景:我们希望有这样一种场景像缓存一样, 即:在内存还足够时,希望能够保留这些对象,当内存不够时,则删除这些对象(当 ...

  7. 你知道Java的四种引用类型吗?

    点击蓝字 关注我们 点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 01 概述 在Java中提供了四个级别的引用:强引用,软引用,弱引用和虚引用. ...

  8. java ref 应用类型_Java中的四种引用类型比较

    1.引用的概念 引用这个概念是与JAVA虚拟机的垃圾回收有关的,不同的引用类型对应不同的垃圾回收策略或时机. 垃圾收集可能是大家感到难于理解的较难的概念之一,因为它并不能总是毫无遗漏地解决Java运行 ...

  9. java的四种引用类型_你知道Java的四种引用类型吗?

    以下文章来源于程序员柯南 ,作者薛勤 点击蓝字关注我们 点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大!01概述 在Java中提供了四个级别的引用: ...

最新文章

  1. 在linux环境下重启oracle数据库,解决密码过期的问题
  2. Javascript中的异步
  3. java http输出,Java HTTP Client输出空JSON
  4. 【模型解读】从“局部连接”回到“全连接”的神经网络
  5. Linux 添加DNS配置
  6. Web开发-Django视图层
  7. squid代理服务器(捎带的SNAT)
  8. python查看数据类型type_python——获取数据类型:type()、isinstance()的使用方法:...
  9. linux用vi查找字符串替换,Linux中vi进行字符替换
  10. 【隐私计算笔谈】MPC系列专题(五):Beaver三元组和BMR协议
  11. Canvas--画直线
  12. 【音频处理】之Ubuntu sox / faad / ffmpeg 使用
  13. 劣质VGA线导致不支持非标准分辨率显示
  14. 云计算中心怎么选址?
  15. python从文件中删除某个字符,后保存该文件
  16. 三校生高考计算机基础知识,计算机基础知识题(单选题)(三校生历年高考真题归纳)...
  17. IEC 61850 Compatible OpenPLC for Cyber Attack Case Studies on Smart Substation Systems
  18. video标签的使用
  19. Bootstrap JS插件使用实例(6)-折叠(手风琴效果)
  20. 对流形(Manifold)的最简单快速的理解

热门文章

  1. 【报告汇】三公里社区争夺战——2021年社区团购研究报告-202102.pdf(附下载地址)
  2. 修改GL_RENDERER
  3. 总结 HTML5+CSS3 一篇够你喝一壶
  4. Hamiltonian Cycle(哈密顿回路)
  5. 外部模拟量速度控制模式(禾川X3E伺服驱动器)
  6. 【抓包工具】win 10 / win 11:Charles 下载、安装、配置(快捷方式、默认端口、登录、https 证书)
  7. 健身时戴什么耳机比较好、盘点几款适合健身的运动耳机
  8. java求长方体_Java练习 SDUT-3337_计算长方体、四棱锥的表面积和体积
  9. 测试两个主机之间的连通性_EEG源连通性:旨在实现大脑网络在时间和空间上的高分辨率...
  10. 什么是MA以及MA的简单应用