在堆中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事就是要确定这些对象之中哪些还活着,哪些对象已经死去.
判断对象是否已经死亡有以下几种算法:
  1. 引用计数法算法
定义 : 给对象中添加一个引用计数器,当有一个地方引用时,计数器加1,引用失效时,就减1,当对象的引用计数器为0时,对象就是不可再被使用的.
特点 : JAVA虚拟机中很少使用这种算法,主要原因是它很难解决对象之间的循环引用问题
  1. 可达性分析算法
定义 : 通过一系列的称为 GC Roots 的对象作为起点,从这些节点开始向下搜索,搜索把走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连(就是从GC Roots 到这个对象不可达)时,则证明此对象是不可用的.如下图
 
上图中的 5,6,7 对象就是不可达的,就是不可用的.
 
1) 哪些对象可以作为 GC Roots 对象呢?
1 虚拟机栈(栈帧中的本地变量表)中引用的对象
2 方法区中类静态属性引用的对象
3 方法区中常量引用的对象
4 本地方法栈中JNI引用的对象
 
 
2) 再谈引用:(从上到下依次减弱)
1 强引用 : 只要强引用还存在,垃圾收集器永远不回收被引用的对象
2 软引用 : 在内存溢出异常之前,回收对象
3 弱引用 : 在下一次 GC 时,无论当前内存是否足够,都会回收被引用的对象
4 虚引用 : 没用,唯一的用处是在对象回收时,会收到一个系统通知
 
 
3) 对象的 finalize() 方法作用
生存还是死亡?
即使在可达性分析算法中不可达的对象,也并非是"非死不可"的,这时候它们暂时处于"缓刑"阶段,要真正宣告一个对象死亡,至少要经历2次标记:
1 如果对象在进行可达性分析后发现对象不可达,那它将会被第一次标记并进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法.当对象没有覆盖finalize()方法,或者finalize()方法已经执行过,虚拟机将这种情况视为没有必要执行
 
2 如果对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queue的队列之中,并在稍后由一个由虚拟机自动建立的,低优先级的Finalizer线程去执行它.这里所谓的招行是指虚拟机会触发这个方法,但并不承诺等待它运行结束,这样做的原因是,如果一个对象在finalize()方法中做耗时的操作,将很可能会导致 F-Queue队列中的其它对象永久处于等待,甚至导致整个内存回收系统线程崩溃, finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次标记,如果对象要在finalize()中成功拯救自己,即只要对象重新和引用链上的任何一个对象发生关联即可,即将自己(this关键字)赋值给某个类变量或者对象的成员变量,那么在第二次标记时它将被移出"即将回收"的集合,如果对象这时候还没有逃脱,那么基本上它真的要被回收了
注:尽量不要用finalize()方法,忘了这个方法
 

4 Java 如何判定是否存活或者死亡的更多相关文章

  1. Java虚拟机判定对象存活算法

    1.引用计数算法 描述:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器值为0的对象就是不可能再被使用的. 特点:实现简单,判定效率高. ...

  2. 深入Java虚拟机--判断对象存活状态

    程序计数器,虚拟机栈和本地方法栈 首先我们先来看下垃圾回收中不会管理到的内存区域,在Java虚拟机的运行时数据区我们可以看到,程序计数器,虚拟机栈,本地方法栈这三个地方是比较特别的.这个三个部分的特点 ...

  3. JVM-对象的存活与死亡

    当Java虚拟机进行垃圾收集的时候,那么它必须要先判断对象,是否还存活,如果存活就不能对它进行回收.所以判断一个对象是否存活是Java虚拟机必须要实现的. 1.对象是否存活 1)引用计数器:给对象添加 ...

  4. java实现判定新旧版本号

    废话不多说,直接上代码 /** * 判断是否为最新版本方法 将版本号根据.切分为int数组 比较 * * @param localVersion 本地版本号 * @param onlineVersio ...

  5. Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  6. Java虚拟机学习笔记(二)--- 判断对象是否存活

    Java堆中存放着所有的对象实例,垃圾收集器在堆进行回收之前,需要判断对象是“存活”还是“死亡”(即不可能再被任何途径引用的对象). 最常见的一种判断对象是否存活算法是引用计数算法, 给对象加一个引用 ...

  7. Java 垃圾回收算法

    在之前Java 运行期数据区一文中,介绍了运行时内存的各个部分.其中程序计数器.虚拟机栈.本地方法栈都随线程消亡,所以,这几个区域的内存分配和回收都具备确定性.而 Java 堆和方法区不同,我们只有在 ...

  8. 《深入理解Java虚拟机》读书笔记2--垃圾回收

    回收哪些内存/对象 引用计数算法 可达性分析算法 finalize()方法 HotSpot实现分析 转载:http://blog.csdn.net/tjiyu/article/details/5398 ...

  9. Java基础(面试题)

    1:面向对象编程有很多重要的特性: 封装,继承,多态和抽象. 2:什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? (1)Java虚拟机是一个可以执行Java字节码的虚拟机进程.J ...

随机推荐

  1. CSS属性操作二

    9.float属性 基本浮动规则 先来了解一下block元素和inline元素在文档流中的排列方式. block元素通常被现实为独立的一块,独占一行,多个block元素会各自新起一行,默认block元 ...

  2. CSS介绍&选择器&选择器优先级

    CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素. 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染). CSS语法 '''se ...

  3. [Android] 通过GridView仿微信动态添加本地图片

    原文:http://blog.csdn.net/eastmount/article/details/41808179 前面文章讲述的都是"随手拍"中图像处理的操作,此篇文章主要讲述 ...

  4. webstorm 添加markdown支持

    第一步:file---setting---plugins---搜索markdown support 安装 第二步:file---settind---file types---增加*.md处理

  5. 【Java源码】树-概述

    树的基本术语 结点(node)由数据元素以及指向子树的地址构成. 若 X 结点有子树,则子树的根结点称为 X 的孩子(child)结点,相应地, X 称为其孩子的双亲(parents)结点,又称父母结 ...

  6. [Bzoj2120]数颜色 (非正解 )(莫队)

    2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 6286  Solved: 2489[Submit][Status][Discuss] ...

  7. Client使用c#和odp.net连接server oracle

    http://blog.csdn.net/educast/article/details/6605655 Oracle.DataAccess.dll有2.X版本和4.X版本,VS2008开发用2.X ...

  8. Rust 1.7.0 语法基础 sep_token 和 non_special_token

    一.分隔符 sep_token 指的是分隔符, 是除了 * 和 + 之外的不论什么符号,通常情况下是使用 , 逗号. 比如: 宏的多个參数分隔,以下代码中的逗号就是 sep_token (target ...

  9. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

  10. NHibernate查询导致Update问题

    用NHibernate,总感觉怪事多罗罗. 比如说,明明我们是在查询,却报错,刨根问底找到出错原因,竟然是因为执行了一些Update甚至Insert!老天,我们明明只是查询而已,什么时候有更新过数据? ...