文章目录

  • Java对象的存活判定与对象引用
    • 对象的存活判定
      • 引用计数算法
      • 可达性分析算法
    • 对象的引用
      • 强引用
      • 软应用
      • 弱引用
      • 虚引用
      • 终结器引用

Java对象的存活判定与对象引用

对象的存活判定

在堆里面存放着Java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就 是要确定这些对象之中哪些还“存活”着,哪些已经“死去”(“死去”即不可能再被任何途径使用的对 象)了。

判定对象存活的方法有引用计数算法和可达性分析算法。

引用计数算法

定义:在对象中添加一个引用计数器,每当有一个地方 引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可 能再被使用的。

它的原理简单,判定效率也比较高,但一般不会使用这个算法来作为判定对象是否存活的依据,因为它有很多额外的情况需要考虑,需要配合大量额外处理才能保证正确地工作,如单纯的引用计数算法不能解决对象之间互相引用的之间循环引用的问题。

可达性分析算法

这个算法的基本思路就是通过 一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过 程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots间没有任何引用链相连, 或者用图论的话来说就是从GC Roots到这个对象不可达时,则证明此对象是不可能再被使用的。

在Java技术体系里面,固定可作为GC Roots的对象包括以下几种:

  • 在虚拟机栈(栈帧中的本地变量表)中引用的对象,譬如各个线程被调用的方法堆栈中使用到的 参数、局部变量、临时变量等。
  • 在方法区中类静态属性引用的对象,譬如Java类的引用类型静态变量。
  • 在方法区中常量引用的对象,譬如字符串常量池(String Table)里的引用。
  • 在本地方法栈中JNI(即通常所说的Native方法)引用的对象。
  • Java虚拟机内部的引用,如基本数据类型对应的Class对象,一些常驻的异常对象(比如 NullPointExcepiton、OutOfMemoryError)等,还有系统类加载器。
  • 所有被同步锁(synchronized关键字)持有的对象。
  • 反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。

除了这些固定的GC Roots集合以外,根据用户所选用的垃圾收集器以及当前回收的内存区域不 同,还可以有其他对象“临时性”地加入,共同构成完整GC Roots集合。譬如后文将会提到的分代收集 和局部回收(Partial GC),如果只针对Java堆中某一块区域发起垃圾收集时(如最典型的只针对新生 代的垃圾收集),必须考虑到内存区域是虚拟机自己的实现细节(在用户视角里任何内存区域都是不 可见的),更不是孤立封闭的,所以某个区域里的对象完全有可能被位于堆中其他区域的对象所引 用,这时候就需要将这些关联区域的对象也一并加入GC Roots集合中去,才能保证可达性分析的正确 性。

对象的引用

在JDK 1.2版之前,Java里面的引用是很传统的定义: 如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,就称该reference数据是代表 某块内存、某个对象的引用。

在JDK 1.2版之后,Java对引用的概念进行了扩充,将引用分为强引用(Strongly Re-ference)、软 引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)4种,这4种引用强 度依次逐渐减弱。

强引用

强引用是最传统的“引用”的定义,是指在程序代码之中普遍存在的引用赋值,即类似“Object obj=new Object()”这种引用关系。无论任何情况下,只要强引用关系还存在,垃圾收集器就永远不会回 收掉被引用的对象。

软应用

软引用是用来描述一些还有用,但非必须的对象。只被软引用关联着的对象,在系统将要发生内 存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存, 才会抛出内存溢出异常。在JDK 1.2版之后提供了SoftReference类来实现软引用。

弱引用

弱引用也是用来描述那些非必须对象,但是它的强度比软引用更弱一些,被弱引用关联的对象只 能生存到下一次垃圾收集发生为止。当垃圾收集器开始工作,无论当前内存是否足够,都会回收掉只 被弱引用关联的对象。在JDK 1.2版之后提供了WeakReference类来实现弱引用。

虚引用

虚引用也称为“幽灵引用”或者“幻影引用”,它是最弱的一种引用关系。一个对象是否有虚引用的 存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚 引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。在JDK 1.2版之后提供 了PhantomReference类来实现虚引用。

终结器引用

即使在可达性分析算法中判定为不可达的对象,也不是“非死不可”的,这时候它们暂时还处于“缓 刑”阶段,要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没 有与GC Roots相连接的引用链,那它将会被第一次标记,随后进行一次筛选,筛选的条件是此对象是 否有必要执行finalize()方法。假如对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用 过,那么虚拟机将这两种情况都视为“没有必要执行”。

如果这个对象被判定为确有必要执行finalize()方法,那么该对象将会被放置在一个名为F-Queue的 队列之中,并在稍后由一条由虚拟机自动建立的、低调度优先级的Finalizer线程去执行它们的finalize() 方法。

终结器引用用于实现对象的finalize()方法,给了对象一次自救的机会,每个对象的finalize()方法智能执行一次!

Java对象的存活判定与对象引用相关推荐

  1. java中对象的生存期_深入理解Java虚拟机-判断对象是否存活算法与对象引用

    我们知道Java中的对象一般存放在堆中,但是总不能让这些对象一直占着内存空间,这些对象最终都会被回收并释放内存,那么我们如何判断对象已经成为垃圾呢?这篇文章会提出两种算法解决这个问题.另外,本文还要谈 ...

  2. 【JVM】对象存活判定算法、GC算法、STW、GC种类详解

    [JVM]对象存活判定算法.GC算法.STW.GC种类详解 文章目录 [JVM]对象存活判定算法.GC算法.STW.GC种类详解 GC主要关注的区域 垃圾标记阶段:对象存活判断 标记阶段:引用计数算法 ...

  3. JVM成神路之GC基础篇:对象存活判定算法、STW、GC种类详解

    引言 在前面分析JVM运行时内存区域时,其中程序计数器.虚拟机栈.本地方法栈三个区域随线程而生,伴线程而亡.而运行期间,栈的每个栈帧所需空间大小,其实在编译期就可大致确定,因此这几个区域的内存分配和回 ...

  4. (六)JVM成神路之GC基础篇:对象存活判定算法、GC算法、STW、GC种类详解

    引言 经过前面五个章节的分析后,对于JVM的大部分子系统都已阐述完毕,在本文中则开始对JVM的GC子系统进行全面阐述,GC机制也是JVM的重中之重,调优.监控.面试都逃不开的JVM话题. 在前面分析J ...

  5. 深入理解JVM03--判断对象是否存活(引用计数算法、可达性分析算法,最终判定),Eclipse设置GC日志输出,引用

    本文是基于周志明的<深入理解Java虚拟机> 堆中几乎存放着Java世界中所有的对象实例,垃圾收集器在对堆回收之前,第一件事情就是要确定这些对象哪些还"存活"着,哪些对 ...

  6. 深入理解JVM(三)——JVM之判断对象是否存活(引用计数算法、可达性分析算法,最终判定),Eclipse设置GC日志输出,引用

    本文转载自https://blog.csdn.net/ochangwen/article/details/51406779 本文是基于周志明的<深入理解Java虚拟机> 堆中几乎存放着Ja ...

  7. java对象与对象引用变量

    Java对象及其引用 先搞清楚什么是堆,什么是栈.  Java开辟了两类存储区域,对比二者的特点 存储区域 存储内容 优点 缺点 回收 栈 基本类型的变量和对象的引用变量 存取速度比堆要快,仅次于寄存 ...

  8. sqlserver2008未将对象引用设置到对象的实例_JVM | Java对象的创建、存储和访问详解...

    引言   Java程序员都知道如何创建对象,不就是一个Person person = new Person()的语句就解决了么?然而,我们只知道new,却对于底层如何实现对象的创建.如何存储到内存中去 ...

  9. java对象 引用 原理,java对象引用和对象值得行为

    关于java对象和传值得问题,偶然间在看js的时候,发现的一个无效转换对象数据的问题,自己感觉有点疑惑,以为是js的特性,随机想在java上面证实一下,结果发现并不是js的特性,java也是如此然后查 ...

最新文章

  1. 微生物绝对定量or相对定量,你选对了吗
  2. 2019年安徽高考最高分出炉:文科681分 理科710分
  3. 跨链(6)波卡Polkadot “系统框架”
  4. 携程基于Flink的实时特征平台
  5. oracle 内存分析工具,IDE 中的分析工具
  6. Linux系统编程20:基础IO之从内核代码深刻理解Linux是如何管理文件及文件描述符的本质是什么
  7. php版谁是卧底,机器人陪你玩“谁是卧底quot;游戏
  8. mybatis---mybatis插件根据接口自动生成xml文件
  9. 你还在纠结英语的发音问题吗,你还老记不住单词吗?
  10. ​新型冠状病毒是对未来自我隔离的预演?
  11. 「第五章」点击劫持(ClickJacking)
  12. python根据模板中的MML,批量生成小区脚本
  13. Spring cloud系列六 Ribbon的功能概述、主要组件和属性文件配置
  14. 医疗卫生信息化领域的一些术语和标准
  15. nodejs入门之数据爬虫
  16. 用电脑搭建视频会议系统的方法
  17. 这个城市最安静的声音 - Suzy
  18. 当代大学生应该如何学习计算机科学
  19. nacos server 安装报错 macOS 10.12.6
  20. 2021年C证(安全员)考试题库及C证(安全员)多少钱

热门文章

  1. Android12 设置主界面和二级菜单顶部空白去除
  2. JS的trim()方法,去掉字符串空格
  3. 苏宁易购升级服务战略:为用户提供家庭场景解决方案
  4. Python 求阶层(n的累乘、n的累加)
  5. 【C语言】操作符详解(超详细)
  6. SONY a7S III解析
  7. python语言实现快速排序以及复杂度的分析总结
  8. 【PAT甲级】2020冬季 PAT 甲级
  9. 广东理工学校教务系统服务器,2021年广东理工学院教务管理系统登录入口【官网】...
  10. 河北-专接本期间整理的 部分微机原理知识点+错题,希望对大家有帮助