zoukankan      html  css  js  c++  java
  • JVM常见垃圾回收算法

    jdk1.7.0_79

      众所周知,Java是一门不用程序员手动管理内存的语言,全靠JVM自动管理内存,既然是自动管理,那必然有一个垃圾内存的回收机制或者回收算法。本文将介绍几种常见的垃圾回收(下文简称GC)算法。

      在Java堆上分配一个内存给实例对象时,此时在虚拟机栈上引用型变量就会存放这个实例对象的起始地址。

    Object obj = new Object(); 

      现在如果我们将变量赋值为null

    obj = null;

      此时可以看到Java堆上的实例对象无法再次引用它,那么它就是被GC的对象,我们称之为对象已死。那虚拟机栈上的obj变量呢?上文JVM入门——运行时数据区》提到过,虚拟机栈是线程独占的,也就是说随着线程初始而初始,消亡而消亡,当线程被销毁后,虚拟机栈上的内存自然会被回收,也就是说虚拟机栈上的这块内存空间不在虚拟机GC范围。下图展示了垃圾回收的内存范围:

      1.对象是否已死算法——引用计数器算法

      对象中添加一个引用计数器,如果引用计数器为0则表示没有其它地方在引用它。如果有一个地方引用就+1,引用失效时就-1。看似搞笑且简单的一个算法,实际上在大部分Java虚拟机中并没有采用这种算法,因为它会带来一个致命的问题——对象循环引用。对象A指向B,对象B反过来指向A,此时它们的引用计数器都不为0,但它们俩实际上已经没有意义因为没有任何地方指向它们。所以又引出了下面的算法。

      2.对象是否“已死”算法——可达性分析算法

      这种算法可以有效地避免对象循环引用的情况,整个对象实例以一个树呈现,根节点是一个称为“GC Roots”的对象,从这个对象开始向下搜索并作标记,遍历完这棵树过后,未被标记的对象就会判断已死,即为可被回收的对象。

    GC算法

      1.标记-清除算法

      等待被回收对象的标记过程在上文已经提到过,如果在被标记后直接对对象进行清除,会带来另一个新的问题——内存碎片化。如果下次有比较大的对象实例需要在堆上分配较大的内存空间时,可能会出现无法找到足够的连续内存而不得不再次触发垃圾回收。

      2.复制算法Java堆中新生代的垃圾回收算法)

    GC算法实际上解决了标记-清除算法带来的内存碎片化问题。首先还是先标记处待回收内存和不用回收的内存,下一步将不用回收的内存复制到新的内存区域,这样旧的内存区域就可以全部回收,而新的内存区域则是连续的。它的缺点就是会损失掉部分系统内存,因为你总要腾出一部分内存用于复制。

      在上文JVM入门——运行时数据区》提到过在Java堆中被分为了新生代和老年代,这样的划分是方便GCJava堆中的新生代就使用了GC复制算法。在新生代中又分为了三个区域:Eden 空间、To Survivor空间、From Survivor空间。不妨将注意力回到这张图的左边新生代部分:

      新的对象实例被创建的时候通常在Eden空间,发生在Eden空间上的GC称为Minor GC当在新生代发生一次GC会将Eden和其中一个Survivor空间的内存复制到另外一个Survivor,如果反复几次有对象一直存活,此时内存对象将会被移至老年代。可以看到新生代中Eden占了大部分,而两个Survivor实际上占了很小一部分。这是因为大部分的对象被创建过后很快就会被GC(这里也许运用了是二八原则)。

      3.标记-压缩算法(或称为标记-整理算法,Java堆中老年代的垃圾回收算法)

      对于新生代,大部分对象都不会存活,所以在新生代中使用复制算法较为高效,而对于老年代来讲,大部分对象可能会继续存活下去,如果此时还是利用复制算法,效率则会降低。标记-压缩算法首先还是“标记”,标记过后,将不用回收的内存对象压缩到内存一端,此时即可直接清除边界处的内存,这样就能避免复制算法带来的效率问题,同时也能避免内存碎片化的问题。老年代的垃圾回收称为“Major GC”。

  • 相关阅读:
    DirectShow自带实例StillCap在回调函数里实现抓图并保存为文件
    x264 VS2008下编译成功
    yuy2_to_i420,yuyv_to_i420
    x264源码阅读
    oracle 归档日志开启、关闭及删除归档日志
    TOMCAT设置JVM
    linux root 操作oracle命令
    struts2 标签判断list是否为空
    linux下mysql 5.5配置
    RHEL 6 下VNC Server 的安装配置
  • 原文地址:https://www.cnblogs.com/yulinfeng/p/7163052.html
Copyright © 2011-2022 走看看