在堆中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事就是要确定这些对象之中哪些还活着,哪些对象已经死去.
判断对象是否已经死亡有以下几种算法:
  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. THUPC2017看题总结

    THUPC2017 看题总结 #2402. 「THUPC 2017」天天爱射击 / Shooting 果题. 求当前子弹能会使多少块木板损坏,发现因为木板会随着子弹数目的增加而更加容易损坏,故此询问具 ...

  2. ATcoder 1983 BBQ Hard

    E - BBQ Hard Time limit : 2sec / Memory limit : 256MB Score : 1400 points Problem Statement Snuke is ...

  3. 中间件序列TDATASET为BUFFER演示代码

    procedure SendStream(const AStream: TStream);var Buffer: array[0..4095] of Byte; // 每包最大4K StartPos, ...

  4. 【python】urllib2

    urllib2.urlopen(url[, data][, timeout]) 请求url,获得请求数据,url参数可以是个String,也可以是个Request参数 没有data参数时为GET请求, ...

  5. topcoder srm 551

    div1 250pt 题意:一个长度最多50的字符串,每次操作可以交换相邻的两个字符,问,经过最多MaxSwaps次交换之后,最多能让多少个相同的字符连起来 解法:对于每种字符,枚举一个“集结点”,让 ...

  6. Office Adobe Acrobat把PDF转换为Word时候提示不支持的Type2字体怎么办

    如下图所示,在使用Adobe Acrobat Pro9将PDF转换为Word的时候出现下面的错误   很简单,不要用Adobe Acrobat Pro9了,用Adobe Acrobat Pro X,还 ...

  7. lightoj 1138 - Trailing Zeroes (III)【二分】

    题目链接:http://lightoj.com/volume_showproblem.php? problem=1138 题意:问 N. 末尾 0 的个数为 Q 个的数是什么? 解法:二分枚举N,由于 ...

  8. nginx内存池

    一.设计原则 (1)降低内存碎片 (2)降低向操作系统申请内存的次数 (3)减少各个模块的开发效率 二.源代码结构 struct ngx_pool_s {     ngx_pool_data_t    ...

  9. 【C#】无损转换Image为Icon 【C#】组件发布:MessageTip,轻快型消息提示窗 【C#】给无窗口的进程发送消息 【手记】WebBrowser响应页面中的blank开新窗口及window.close关闭本窗体 【手记】调用Process.EnterDebugMode引发异常:并非所有引用的特权或组都分配给呼叫方 【C#】DataRowState演变备忘

    [C#]无损转换Image为Icon 如题,市面上常见的方法是: var handle = bmp.GetHicon(); //得到图标句柄 return Icon.FromHandle(handle ...

  10. wsdl2objc定制(一)namespace

    1.问题抛出: 如今还是有非常多人使用 wsdl2objc 来调用webservice,可是有时候会有不开心的事情发生, <soap:Envelope xmlns:soap="http ...