JVM——垃圾收集器(一)——如何判断对象“已死”

目录:

1.为什么要了解垃圾回收机制?

2.哪几类内存需要进行垃圾收集?

3.如何判断对象“已死”?——两种算法

4.引用的细分

5.对象的自救

1.为什么要了解垃圾回收机制?

当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为系统达到更高并发了的瓶颈时,我们就需要对这些“自动化”技术实施必要的监控和调节。

2.哪几类内存需要进行垃圾收集?

java运行时内存中,程序计数器、虚拟机栈、本地方法栈3个区域是线程私有的,随线程而生,随线程而灭;而Java堆和方法区则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,我们只有在程序处于运行期间才能知道会创建哪个对象,这部分内存的分配和回收都是动态的,垃圾收集器关注的也是这部分内存。

3.如何判断对象“已死”?

引用计数算法

来记录一个对象被引用的次数,当引用计数器为0时,代表这个对象不再被使用。

优点:实现简单,判断效率也很高。

缺点:它很难解决对象之间相互循环引用的问题。

可达性分析算法:

在主流的商用程序语言的主流实现都是通过可达性分析来判断对象是否存活的。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用相连时,证明此对象是不可用的。

java语言中,可作为GC Roots的对象包括下面几种:

①虚拟机栈(栈帧中的本地变量表)中引用的对象。

②方法区中静态属性引用的对象。

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

④本地方法栈中JNI(即一般说的Native方法)引用的对象。

4.引用的细分:

java中的引用定义很传统:如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,就称这块内存代表着一个引用。这种定义很纯粹,但是太过狭隘,一个对象在这种定义下只有被引用或者没有被引用两种状态,对于如何描述一些“食之无味,弃之可惜”的对象就显得无能为力。

我们希望能描述这样一组对象:当内存空间还足够时,则能够保存在内存中;如果内存空间在进行垃圾收集后还是非常紧张,就可以抛弃这些对象。

在JDK1.2之后,java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4种。

强引用:就是指在程序代码之中普遍存在的,类似“Object obj=new Object()”这类引用,只要强引用还在,垃圾收集器永远不会回收掉被引用的对象。

软引用:是用来描述一些还有用但并非必须的哦对象。对于软引用关联着的对象,在系统将要发生的内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出的异常。

弱引用:也是用来描述非必须对象的,但是他的强度比软引用更弱一点,只能生存到下一次垃圾收集之前。

虚引用:最弱的引用关系,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象的实例。为一个对象设置虚引用的唯一目的就是能够在这个对象被收集器回收时收到一个系统通知。
 

5.对象的自救

即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候他们暂时处于“缓刑”阶段,要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是对此对象是否有必要执行finalize()方法。

当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过(对象自救机会只有一次),虚拟机将这两种情况都视为“没有必要执行”。

如果这个对象被判定为有必要执行的finalize()方法,那么这个对象将会被放置在一个叫做F-Queue的队列之中,并在稍后由一个由虚拟机自动建立的、低优先级的Finalize线程去执行它。这里所谓的“执行”是指虚拟机会触发这个方法,但并不承诺会等待它运行结束,这样做的原因是,如果一个对象在finalize()方法中执行缓慢,或者发生了死循环,很可能回到藕汁F-Queue队列中的其他对象永久处于等待状态,甚至导致整个内存回收系统崩溃。

Finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将堆F-Queue中的对象进行第二次小规模的标记,如果对象要在finalize()中成功拯救自己——只需要重新与引用链的任何一个对象建立关联即可,譬如把this赋值给某变量或者对象的成员变量,拿在第二次标记时,它将被移除出“即将回收”的集合;如果对象这个时候还有逃脱,那基本上他就真的被回收了。

猜你喜欢

转载自my.oschina.net/u/3786691/blog/1805154
今日推荐