<commit_before>---
layout: post
title: 如何判断对象已死 
categories: Java
description: 如何判断对象已死 
keywords: Java
---

######  概述：垃圾回收是根据对象是否已死来判断是否回收，那么判断对象存活的算法有哪些，java采用的是哪一种算法，本文将一一道出


####  一、引用计数法



很多教科书判断对象是否存活的算法是这样昨给对象中添加一个引用计数器，每当有
一个地方引用它时，计数器值就加1:当引用失效时，计数器值就减1；任何时刻计数器为
0的对象就是不可能再被使用的。


 客观地说，引用计数算法（Reference Counting)的实现简单，判定效率也很高，在大部分情况下它都是一个不错的算法.也有一些比较著名的应用案例，例如微软公司的COM(Component Object Model)技术、使用Action5cript 3的FIashPlayer.Python语言和在游戏脚本领域被广泛应用的Squirzel中都使用了引用计数算法进行内在管。但是，至少主流的Java虚拟机里面没有选用引用计数算法来管理内存，其中最主要原因是它很难解决对象之间互循环引用的问题。
 

#### 二、可达性分析算法

在主流的商用程序语言（Java、C#，甚至包括前面提到的古老的Lisp）的主流实现中，都是称通过可达性分析（Reachability Analysis）来判定对象是否存活的。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点，从这些节点开始向下搜索，搜索所走过的路径称为引用链（Reference Chain），当一个对象到GC Roots没有任何引用链相连（用图论的话来说，就是从GC Roots到这个对象不可达）时，则证明此对象是不可用的。如下图所示，对象object 5、object 6、object 7虽然互相有关联，但是它们到GC Roots是不可达的，所以它们将会被判定为是可回收的对象。


![图像](http://img.blog.csdn.net/20160612162410328)

在java钟只有以下的对象才可以被作为GC Root. 
1>虚拟机栈(栈帧中的本地方法表)中引用的对象。 
2>方法区中类静态属性引用的对象。 
3>方法区中常量引用的对象。 
4>本地方法栈JNI（即一般说的Native方法）的引用对象。 

关于引用: 
  在jdk1.2之前，java中的引用时这样定义的:如果reference类型的数据中存储的是另一块内存的起始地址，就称这块内存代表着一个引用。这样定义过于狭隘，因为这是一个对象只有引用和被引用两种状态，描述一下"食之无味，弃之可惜"的对象则无能无力，我们希望描述这样的一类对象，当内存空间还够是，则能留在内存中，否则内存进行垃圾回收后还紧张，那么可以抛弃这些对象，jdk1.2后对引用进行了扩充，分为:强引用(Strong Reference)，软引用(Soft Reference),弱引用(Weak Reference),虚引用(Phantom Reference)四种。 
  3.1 强引用。 
   该引用是代码中普通存在的，例如Object objA = new Object(),只要强引用存在，垃圾收集器永远不会回收掉被引用的对象。 
  3.2 软引用。 
  该引用用来描述一些还有用，但是并非必须得对象，在系统将要爆发内存溢出之前，将会把这些对象列在进行回收的范围之内，进行二次回收后如果还是内存不足，这时候才跑出内存溢出的错掉只被弱引用关联的对象。
   3.3弱引用。 
   该引用也是用来描述非必须对象的，强度比软引用更弱被弱引用引用的对象只能存活到下一次垃圾回收之前。当垃圾收集器工作时，无论当前内存是否足够，都会回收掉只被弱引用关联的对象。 
  3.4 虚引用也称为幻影引用。 
  是最弱的一种的引用，一个对象是否存活与其生存周期没有什么影响，设置该引用的目的仅仅 是希望这个对象被释放的时候能够收到一个系统通知。 

生存还是死亡? 

  如果进行垃圾回收的时候发现一个对象没有在GC Root链上，那么就需要进行两次的标记过程，如果当前发现没有关联在GC Root链上，那么就会进行第一次标记并且进行一次筛选，如果此时对象的finalize()方法没有被覆盖或该方法已经被虚拟机调用过，那么此时将被标记为没有必要执行，此时该对象会被放入”即将回收“集合，否则就会放入F-Queue的对象中等待执行finalize（)方法，如果在此方法中对象将自己与GC Root链上的任何一个对象关联，那么就会被溢出”即将回收“集合。






<commit_msg>Update 2016-6-12-obj-islive.md<commit_after>---
layout: post
title: 如何判断对象已死 
categories: Java
description: 如何判断对象已死 
keywords: Java
---

######  概述：垃圾回收是根据对象是否已死来判断是否回收，那么判断对象存活的算法有哪些，java采用的是哪一种算法，本文将一一道出


####  一、引用计数法



很多教科书判断对象是否存活的算法是这样昨给对象中添加一个引用计数器，每当有
一个地方引用它时，计数器值就加1:当引用失效时，计数器值就减1；任何时刻计数器为
0的对象就是不可能再被使用的。


 客观地说，引用计数算法（Reference Counting)的实现简单，判定效率也很高，在大部分情况下它都是一个不错的算法.也有一些比较著名的应用案例，例如微软公司的COM(Component Object Model)技术、使用Action5cript 3的FIashPlayer.Python语言和在游戏脚本领域被广泛应用的Squirzel中都使用了引用计数算法进行内在管。但是，至少主流的Java虚拟机里面没有选用引用计数算法来管理内存，其中最主要原因是它很难解决对象之间互循环引用的问题。
 

#### 二、可达性分析算法

在主流的商用程序语言（Java、C#，甚至包括前面提到的古老的Lisp）的主流实现中，都是称通过可达性分析（Reachability Analysis）来判定对象是否存活的。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点，从这些节点开始向下搜索，搜索所走过的路径称为引用链（Reference Chain），当一个对象到GC Roots没有任何引用链相连（用图论的话来说，就是从GC Roots到这个对象不可达）时，则证明此对象是不可用的。如下图所示，对象object 5、object 6、object 7虽然互相有关联，但是它们到GC Roots是不可达的，所以它们将会被判定为是可回收的对象。


![图像](http://img.blog.csdn.net/20160612162410328)

在java钟只有以下的对象才可以被作为GC Root. 

1>虚拟机栈(栈帧中的本地方法表)中引用的对象。 

2>方法区中类静态属性引用的对象。 

3>方法区中常量引用的对象。 

4>本地方法栈JNI（即一般说的Native方法）的引用对象。 

关于引用: 

  在jdk1.2之前，java中的引用时这样定义的:如果reference类型的数据中存储的是另一块内存的起始地址，就称这块内存代表着一个引用。这样定义过于狭隘，因为这是一个对象只有引用和被引用两种状态，描述一下"食之无味，弃之可惜"的对象则无能无力，我们希望描述这样的一类对象，当内存空间还够是，则能留在内存中，否则内存进行垃圾回收后还紧张，那么可以抛弃这些对象，jdk1.2后对引用进行了扩充，分为:强引用(Strong Reference)，软引用(Soft Reference),弱引用(Weak Reference),虚引用(Phantom Reference)四种。
  
  3.1 强引用。 
  
   该引用是代码中普通存在的，例如Object objA = new Object(),只要强引用存在，垃圾收集器永远不会回收掉被引用的对象。 
   
  3.2 软引用。 
  
  该引用用来描述一些还有用，但是并非必须得对象，在系统将要爆发内存溢出之前，将会把这些对象列在进行回收的范围之内，进行二次回收后如果还是内存不足，这时候才跑出内存溢出的错掉只被弱引用关联的对象。
  
   3.3弱引用。 
   
   该引用也是用来描述非必须对象的，强度比软引用更弱被弱引用引用的对象只能存活到下一次垃圾回收之前。当垃圾收集器工作时，无论当前内存是否足够，都会回收掉只被弱引用关联的对象。 
   
  3.4 虚引用也称为幻影引用。
  
  是最弱的一种的引用，一个对象是否存活与其生存周期没有什么影响，设置该引用的目的仅仅 是希望这个对象被释放的时候能够收到一个系统通知。 

生存还是死亡? 

  如果进行垃圾回收的时候发现一个对象没有在GC Root链上，那么就需要进行两次的标记过程，如果当前发现没有关联在GC Root链上，那么就会进行第一次标记并且进行一次筛选，如果此时对象的finalize()方法没有被覆盖或该方法已经被虚拟机调用过，那么此时将被标记为没有必要执行，此时该对象会被放入”即将回收“集合，否则就会放入F-Queue的对象中等待执行finalize（)方法，如果在此方法中对象将自己与GC Root链上的任何一个对象关联，那么就会被溢出”即将回收“集合。







{'fraction_non_alphanumeric': 0.09349693251533742, 'fraction_numerical': 0.021840490797546012, 'mean_word_length': 10.481690140845071, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1758300', 'n_tokens_mistral': 3419, 'n_tokens_neox': 3754, 'n_words': 131}