GC的概念和算法

      GC全称是Garbage Collection,就是垃圾收集。在C++中由程序员自己收集无用的垃圾对象,释放内存空间,而在java中,这部分工作交由虚拟机自动完成,后台会有一个垃圾回收线程自动扫描。GC的概念不是java提出的。Java中,GC的对象是堆空间和永久区。

一.如何判断对象“已死”

      垃圾回收的前提是如何判断该对象是垃圾对象,程序已经不需要了,可以进行回收。

1.引用计数法:

      通过给对象添加一个引用计数器,来标记一个对象是不是垃圾对象,是不是应该回收。当计数器为0时,表示该对象不再被使用了。微软公司的COM技术和python就使用了这种算法进行内存管理。但这种算法无法解决对象间循环引用的问题,java没有采用这种算法。

2.可达性分析算法:

      目前主流语言都是用这种算法,如java、C#等。这种算法的基本思想是通过被称为“GC Roots”的对象作为起点,从这些起点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象不再被使用。
      在java语言中,可作为GC Roots的对象包括:
      a.虚拟机栈(栈帧中的本地变量表)中引用的对象
      b.方法区中类静态属性引用的对象
      c.方法区中常量引用的对象
      d.本地方法栈中JNI引用的对象 

3可触及性:
      从根节点可以触及到的对象,就是可触及对象。
     一旦所有引用被释放,该对象也不是一定会收,而是处于可复活状态,因为在finalize()中可能复活该对象。finalize()方法是对象逃脱死亡的最后机会,只要在finalize()方法中重新与引用链上的任何对象建立关联即可。注意finalize()方法只会被虚拟机调用一次,如果对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过了,那么虚拟机将不会执行finalize()方法。
       在finalize()后,如果仍然是从根节点不可触及的,则进入不可触及状态,不可触及的对象不可能复活,将被虚拟机回收。
       注意:应避免使用finalize(),操作不慎可能导致错误。

二.GC算法

1.标记清除算法:
       标记-清除算法是现代垃圾回收算法的思想基础。标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。一种可行的实现是,在标记阶段,首先通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象。然后,在清除阶段,清除所有未被标记的对象。

          
      这种算法主要有两个不足:一是效率问题,标记和清除两个过程效率都不高;二是空间问题,标记清除之后会产生大量不连续的内存碎片。
2.复制算法:
  将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。

        
    实际使用中,一般将新生代划分为一块较大的Eden 空间和两个较小的 Survivor 空间(From Space, To Space)(8:1:1),每次使用Eden 空间和其中的一块 Survivor 空间,当进行回收时,将该两块空间中还存活的对象复制到另一块 Survivor 空间中。当对象在 Survivor 区躲过一次 GC 后,其年龄就会+1。 默认情况下年龄到达 15 的对象会被移到老生代中。   

    复制算法解决的是标记清除算法的效率问题,它不适用于存活对象较多的场合,因为短命对象归为新生代,长命对象归为老年代。因此老年代存活对象较多,所以复制算法不适合老年代。
3.标记压缩:
    标记-压缩算法,也称为标记整理算法,它也是首先需要从根节点开始,对所有可达对象做一次标记。但之后,它并不简单的清理未标记的对象,而是将所有的存活对象压缩到内存的一端。之后,清理边界外所有的空间。

       
        这种算法解决的是空间碎片问题,它适用于存活对象较多的场合,如老年代。

三.Stop-The-World

      由GC引起了一个关键性的问题,Stop-The-World,简称STW。它是Java中一种全局暂停的现象。全局停顿,所有Java代码停止,native代码可以执行,但不能和JVM交互。这种现象多半由于GC引起的,此外Dump线程、死锁检查、堆Dump都有可能引起STW,但这几种情况一般都是人为触发。
      新生代的GC,也就是minorGC会比较短,一般在毫秒级。老年代的GC有时候也在零点几秒以内完成,但有时会很长,达到几秒、几十秒甚至更长,这主要取决于当时堆的实际情况。
        Stop-The-World的危害长时间服务停止,没有响应。对于一些HA系统,可能引起主备切换,危害生产环境。

四.GC的种类

1.Minor GC:
      Minor GC指新生代GC,即发生在新生代(包括Eden区和Survivor区)的垃圾回收操作,当新生代无法为新生对象分配内存空间的时候,会触发Minor GC。因为新生代中大多数对象的生命周期都很短,所以发生Minor GC的频率很高,虽然它会触发stop-the-world,但是它的回收速度很快。
2.Major GC
       Major GC清理Tenured区,用于回收老年代,出现Major GC通常会出现至少一次Minor GC。
3.Full GC
      Full GC是针对整个新生代、老生代、元空间(metaspace,java8以上版本取代perm gen)的全局范围的GC。Full GC不等于Major GC,也不等于Minor GC+Major GC,发生Full GC需要看使用了什么垃圾收集器组合,才能解释是什么样的垃圾回收。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值