java垃圾回收算法

一、垃圾标记算法

要回收垃圾,则要知道哪些是垃圾

1.引用计数算法

判断对象的引用数量,每个对象实例都有一个引用计数器,被引用+1、完成引用-1

优点:执行效率高,程序执行受影响较小

缺点:无法检测出循环引用的情况,导致内存泄漏

2.可达性分析算法

判断对象的引用链是否可达来决定对象是否可以被回收

可以作为gcroot的对象 :
                                                       虚拟机栈中引用的对象(栈帧中的本地变量表)
                                                       方法区中的常量引用的对象
                                                       方法区中的类静态属性引用的对象
                                                       本地方法栈中jni(native方法)的引用对象
                                                       活跃的线程引用对象

二、垃圾回收算法

光标记了哪些是垃圾还不行,还要将其回收

1.标记-清除算法

标记:使用可达性分析算法,从gcroot集合扫描对,对存活对象标记

清除:回收不可达对象的内存

缺点:  产生不连续的内存碎片,当需要较大的内存区域的时候,会导致内存不够再次触发gc

2.复制算法

它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对 象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

优点:解决了碎片化问题,顺序分配内存简单高效,适用于对象存活率低的场景(新生代)

缺点:空间利用率不高(比如200MB的空间,实际只能用上100MB代价太大了)

3.标记整理算法 

标记过程仍然与标记 - 清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,再清理掉端边界以外的内存区域。

优点:避免了内存的不连续、提高了内存的利用率、适用于对象存活率高的场景(老年代)

缺点:它对内存变动更频繁,需要整理所有存活对象的引用地址,在效率上比复制算法要差很多

4.分代收集算法 

是融合上述3种基础的算法思想,而产生的针对不同情况所采用不同算法的一套组合拳。对象存活周期的不同将内存划分为几块。 一般是把 Java 堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。

 

                           

新生代中的对象朝生夕死,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。每次 Minor GC,会将之前 Eden 区和 From 区中的存活对象复制到 To 区域。第二次 Minor GC 时,From 与 To 职责兑换,这时候会将 Eden 区和 To 区中的存活对象再复制到 From 区域,以此反复,对象Minor GC达到一定次数后,便可进入老年代。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须 使用标记-清理或者标记 - 整理算法来进行回收。  

对象如何晋升到老年代:

  1. 经历一定Minor GC次数后依然存活的对象。虚拟机给每个对象定义了一个对象年龄(Age)计数器。每次GC年龄+1,默认15岁会被移入老年代
  2.  Eden或Survivor区放不下时。对象先在Eden区分配空间,当Eden区放不下会触发一次Minor GC,将Eden区还存活的对象放入Survivor区,当Survivor区放不下时,由老年代做分配担保,进入老年代
  3.  新生的大对象。大对象指需要大量连续内存空间的对象,这部分对象不管是不是“朝生夕死”,都会直接进到老年代。这样做主要是为了避免在 Eden 区及2个 Survivor 区之间发生大量的内存复制。(-XX:+PretenuerSizeThreshold可指定大对象的大小,超过设定值直接进入老年代)

                                                        

三、GC分类

Minor GC:发生在年轻代

Full GC:发生在老年代,一般会伴随年轻代的垃圾收集,所以叫full gc

 

触发Full GC的条件:说出至少三条
                                    1. 老年代空间不足
                                    2. 永久代空间不足(8以后取消了)
                                    3. CMS GC出现promotion failed, concurrent mode failure
                                    4. Minor GC晋升到老年代的平均大小大于老年代的剩余空间, 检查老年代空间是否小于Minor要到老年代对                                         象的大小, 如果小, 则只需Full GC
                                    5. 调用System.gc(), 至于回不回收还是虚拟机来决定
                                    6. 使用RMI来进行RPC或管理的JDK应用, 每小时执行1次Full GC

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值