您的位置:首页 > 其它

2.JVM垃圾回收机制-什么时候回收内存

2018-03-08 09:42 260 查看
  在前面的文章中,我们介绍过JVM垃圾回收机制负责的是堆和方法区的内存。

参考:http://blog.csdn.net/u011983531/article/details/49227013

在本篇中,将重点关注堆和方法区的内存何时会被回收。

简单来说,当一个对象已经死亡时,就会对其进行回收,那么根据什么方法来判断对象是否死亡呢?

一.引用计数算法

算法描述:给对象添加一个引用计数器,当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是死亡的。

  引用计数算法很简单,判断效率也很高,但是JVM没有选用它来管理内存。原因是什么呢?主要是因为它很难解决循环引用的问题。

二.根搜索算法

算法描述:通过一系列名为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所有走过的路径称为“引用链”,当一个对象到“GC Roots”没有任何引用链想连时,则证明此对象是不可用的。

JVM中,可以作为“GC Roots”的对象包括下面几种:

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

换句话说,就是当前所有正在被调用的方法的引用类型的参数、局部变量、临时值。

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

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

Java类中的静态变量

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

Java类在运行时引用的常量、String常量池(StringTable)里的引用

对于上面的解释,可能很多人都还不是很明白跟搜索算法是怎么工作的,下面用另一种方法解释一遍。

  所谓“GC roots”,或者说tracing GC的“根集合”,就是一组必须活跃的引用(注:是引用,不是对象)。

Tracing GC的根本思路就是:给定一个集合的引用作为根出发,通过引用关系遍历对象图,能被遍历到的(可到达的)对象就被判定为存活,其余对象(也就是没有被遍历到的)就自然被判定为死亡。Tracing GC的本质是通过找出所有活对象来把其余空间认定为“无用”,而不是找出所有死掉的对象并回收它们占用的空间。 GC roots这组引用是tracing GC的起点。

  所以,要实现语义正确的tracing GC,就必须要能完整枚举出所有的GC roots,否则就可能会漏扫描应该存活的对象,导致GC错误回收了这些被漏扫的活对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息