简单介绍垃圾回收算法

  最近在看深入了解java虚拟机这本书,java最让人心动但是最复杂的就是它的自动内存管理机制,而对于系统来说,只有采用合适的内存管理,才能使得我们的系统响应更快。

  简单介绍垃圾回收算法:

  1.标记-清除算法:

  概念:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象

  那么就有疑问了,怎么标记的呢?

  标记过程:
  (1)引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数值就加1;当引用失效时,计数器就减1;任何时刻计数器为0的对象就是不可能再被使用的

  这个咋一看觉得很美好,但是遇到一种场景下,对象objA和对象objB都有字段,并且令objA和objB互为对方的某个字段,此时置两个对象都为null,显然可以知道这两个对象是不能  再被访问,但是依照引用计数法来看的话显然不能被回收,因为都加了1,但是我们再也用不了了,引用计数法达不到我们的目的,所有java虚拟机并没有使用引用计数器来处理

  (2)可达性分析算法:当一个对象到GC Roots没有任何引用链相连,则证明此对象不可达到

  什么是GC Roots?

  在java语言,可作为GC Root的对象:
  虚拟机栈(栈帧中的本地变量表)中引用的对象
  方法区中类静态属性引用的对象
  方法区中常量的引用的对象
  本地方法栈中JNI引用的对象

  对于java虚拟机采用的就是GC Roots,那到底是怎么判断对象是生存还是死亡呢?

  一个对象要真正地宣布死亡,需要经历至少两次的标记过程,并进行筛选,筛选条件是此对象是否有无必要执行finalize()方法。当对象没有覆盖finalize方法或者finalize方法已经被  虚拟机调用过,则视为没有必要执行
  如果这个对象被判定为有必要执行finalize()方法,则这个对象会放置在一个F-Queue的队列之中,并在稍后由一个由虚拟机自动建立的、低优先级的Finalizer线程执行它。而对  于对象来说,finalize()方法是对象逃脱死亡的最后机会

  演示对象自我拯救的过程:

  

public class FinalizeEscapeGC {

    public static FinalizeEscapeGC SAVE_HOOK=null;

    public void isAlive(){
        System.out.println("yes,i am still alive");
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("finalize method executed");
        FinalizeEscapeGC.SAVE_HOOK=this;
    }

    public static void main(String[] args) throws InterruptedException {
        SAVE_HOOK=new FinalizeEscapeGC();

        SAVE_HOOK=null;
        System.gc();

        Thread.sleep(500);
        if (SAVE_HOOK!=null){
            SAVE_HOOK.isAlive();
        }else {
            System.out.println("no,i am dead");
        }

        SAVE_HOOK=null;
        System.gc();

        Thread.sleep(500);
        if (SAVE_HOOK!=null){
            SAVE_HOOK.isAlive();
        }else {
            System.out.println("no,i am dead");
        }
    }
}

   2.复制算法

  概念:将可用的内存容量划分为大小相等的两块,每次只使用其中的一块,每次垃圾回收对整个半区进行内存回收
  ==>演变
  将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中的一块Survivor。回收时,将Eden和Survivor中存活的对象一次性复制到另一块Survivor空   间。HotSpot默认Eden:Survivor=8:1,这意味着10%内存被浪费。但当Survivor不够用时,需要依赖老年代进行分配担保

  3.标记整理算法

  概念:让所有存活对象都向一端移动

  目的:节省jvm内存的使用

posted @ 2017-11-01 19:58  还想着呢  阅读(133)  评论(0)    收藏  举报