GC的三种收集方法

注:转自 

https://blog.csdn.net/skp127/article/details/51993696

https://blog.csdn.net/zdy0_2004/article/details/43030659

jvm 分代回收详解http://www.blogjava.net/ldwblog/archive/2013/07/24/401919.html

3中基本的回收算法: 1. 标记-清除法 2. 复制 算法 3.标记-整理法

1,标记-清除法

        将不用的对象实例标记,然后清除 。 缺点 会产生大量内存碎片。

2 ,复制 算法

        把内存分成AB 2块,每次只是用其中的一块。当A块用完后,把A中还存活的对象复制到B中,然后将A块内存清空。不会产生内存碎片。缺点 内存使用率不高。

3,标记-整理法

        当存活的实例过多时,如果复制的话,效率不高,不合适老生代。 这时,把存活的对象标记出来,全部移动到一端,然后对另外一部分进行清除。

一些高级的GC算法 ,分代回收 、增量回收、并行回收

1. 分代回收

        在分代回收中,对象按照生成的时间进行分代,刚刚生成不久的年轻对象划为新生代(Young generation),而存活了较长时间的对象则划为老生代(Old generation)。

            在java Jvm中,针对堆内存的新生代 采用复制算法,将新生代分为按8:1:1 分为Eden 区 、Survivor From 区、Survivor To 区。其中Survivor Form 区和Survivor To 区没有区别 ,在该区域的回收一般比较频繁,称作:Minor GC;针对老生代,由于该区的对象存活时间比较长,比较稳定,一般采取标记-整理法。在该区域额度回收称作Major GC 或者 Full GC ,速度较慢,是Minor的10倍。

            按照前面的方式,从老生代对象对新生代的引用怎么办呢?如果指扫描新生代区域的话,那么从老生代对新生代的引用就不会被检测到。如果一个年轻的对象只有来自老生代的引用,就会被误认为已经“死亡”了。因此,在分代回收中,会对对象的更新进行监视,将从老生代对新生代的引用,记录在一个叫做记录集(remembered set)的表中。在执行小回收的过程中,这个记录集也作为一个根来对象。为了让分代回收正确工作,必须使记录集的内容报纸更新。为此,在老生代到新生代的引用产生的瞬间,就必须对该引用进行记录,而负责执行这个操作的子程序,需要被嵌入到所有设计对象更新操作的地方。这个负责记录引用的子程序是这样工作的:设有两个对象A和B,当对A的内容进行改写并加入对B的引用,如果A属于老生代对象,并且B属于新生代对象,则将该引用添加到记录集中。这种检查程序需要对所有涉及修改对象内容的地方进行保护,因此被成为写屏障(Writes barrier).写屏障不仅用于分代回收,同时也用在很多其他的GC算法中。

2.增量回收 

        在对实时性要求很高的程序中,比起缩短GC的平均中断时间,往往更重视缩短GC的最大中断时间。例如,在机器人的姿势控制程序中,如果因为GC而让控制程序中断了0.1秒,机器人可能就摔倒了。或者车辆控制程序因为GC而延迟相应的花,后果也是不堪设想的。在这些对实时性要求很高的程序中,必须能够对GC所产生的中断做出预测。例如可以将最多中断10毫秒作为附加条件。在一般的GC算法中,GC产生的中断时间与对象的数量和状态有关。因此,为了维持程序的实时性,不等到GC全部完成,而是将GC操作细分成多个部分逐一执行。这种方式被成为增量回收(Incremental GC)。在增量回收中GC过程是渐进的,再回首过程中程序本身会继续运行,对象之间的引用关旭也可能发生变化。如果已经完成扫描和标记的对象被修改,对新的对象产生了引用,这个新的对象就不会被标记,明明是存“存活”的对象却被回收掉了。为了避免这样的问题,和分代回收一样也采用了写屏障。当已经被标记的对象的引用关系发生变化时,通过写屏障会将新被引用的对象作为扫描的起始点记录下来。由于增量回收的过程是分布渐进式的,可以将中断时间控制在一定长队之内。另一方面由于终端操作需要消耗一定的时间,GC所消耗的总时间就会相应的增加。

3. 并行回收 

            最近的计算机中,一块芯片上搭载多个CPU核心的多核处理器已经逐渐普及。例如core i7就拥有6核12线程。

在这样的环境中,就需要通过利用多线程来充分发挥CPU的性能。并行回收正是通过最大限度利用CPU的处理能力来进行GC操作的一种方式。并行回收的基本原理是,在原有的程序运行的同事进行GC操作,这一点和增量回收是相似的。不过,相对于在一个CPU上进行GC任务分割的增量回收来说,并行回收可以利用多CPU的性能,尽可能让这些GC任务并行进行。由于软件运行和GC操作是同事进行的,因此就会遇到和增量回收同样的问题。为了解决这个问题,并行回收也需要用写屏障来对当前状态信息保持更新。不过,让GC操作完全并行,而一点不影响原有程序运行,是做不到的。因此在GC操作的某些特定阶段,还是需要中断原有程序的运行。

一些名词解释

            新生代 GC(Minor GC):指发生在新生代的垃圾收集动作,因为 Java 对象大多都具备朝生夕灭的特性,所以 Minor GC 非常频繁,一般回收速度也比较快。

             老年代 GC(Major GC  / Full GC):指发生在老年代的 GC,出现了 Major GC,经常会伴随至少一次的 Minor GC(但非绝对的,在 ParallelScavenge 收集器的收集策略里就有直接进行 Major GC 的策略选择过程) 。MajorGC 的速度一般会比 Minor GC 慢 10倍以上。


            虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在 Eden 出生并经过第一次 Minor GC 后仍然存活,并且能被 Survivor 容纳的话,将被移动到 Survivor 空间中,并将对象年龄设为 1。对象在 Survivor 区中每熬过一次 Minor GC,年龄就增加 1 岁,当它的年龄增加到一定程度(默认为 15 岁)时,就会被晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold 来设置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值