(五十七)什么是GC

GC:Garbage Collection

一、GC的任务

释放垃圾占有的内存,防止内存泄漏。有效的使用可以使用的内存,对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收。

二、怎样定义垃圾

①引用计数算法

是一种简单且低效的方法。每当一个地方引用它(对象)时,计数器+1;引用失效时,计数器-1;计数值=0——不可能再被引用。

 缺点:但是不能解决相互引用问题,所以JVM没有用此算法

public class ReferenceCountingGC {

    public Object instance;

    public ReferenceCountingGC(String name){}
}

public static void testGC(){

    ReferenceCountingGC a = new ReferenceCountingGC("objA");
    ReferenceCountingGC b = new ReferenceCountingGC("objB");

    a.instance = b;
    b.instance = a;

    a = null;
    b = null;
}

 我们可以看到,最后这2个对象已经不可能再被访问了,但由于他们相互引用着对方,导致它们的引用计数永远都不会为0,通过引用计数算法,也就永远无法通知GC收集器回收它们。

②可达性分析算法

利用JVM维护的对象引用图,从根开始遍历对象的引用图,同时标记遍历到的对象。当遍历结束后,未被标记的对象就是目前已不再被使用的对象,可以被回收了。

 

 

三、怎样回收垃圾(垃圾回收算法)

在确定了哪些垃圾可以被回收后,垃圾收集器要做的事情就是开始进行垃圾回收,但是这里面涉及到一个问题是:如何高效地进行垃圾回收。

①标记-清除算法

此方法缺点:

一是效率问题,标记和清除效率都不高,

二是空间问题,标记清除后会产生大量不连续的内存碎片,一些需要连续内存的,用不了这些空间

②标记-复制算法

为了解决内存碎片问题,一种称为“复制”(Copying)的收集算法出现了,他将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这块的内存用完了,就将还存活这的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对整个半区进行内存回收。

优点:内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。

缺点:只是这种算法的代价是将内存缩小为了原来的一半,未免太高了一点。

若存活的较多,也很浪费时间

③标记-整理算法

该算法标记阶段和Mark-Sweep一样,但是在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理掉端边界以外的内存。所以,特别适用于存活对象多,回收对象少的情况下。效率比“标记-清理”算法低,但不会产生内存碎片。

 

⑤按代回收算法

根据对象的生命周期长短特点将其进行分块,根据每块内存区间的特点,使用不同的回收算法,从而提高垃圾回收的效率。比如Java虚拟机中的堆就采用了这种方法分成了新生代和老年代。然后对于不同的代采用不同的垃圾回收算法。新生代使用了标记-复制算法,老年代使用了标记-整理清除算法。

分代收集算法分代收集算法(Generational Collection)严格来说并不是一种思想或理论,而是融合上述3种基础的算法思想,而产生的针对不同情况所采用不同算法的一套组合拳。对象存活周期的不同将内存划分为几块。一般是把 Java 堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用标记-清理或者标记 --- 整理算法来进行回收。

三、是否可以主动通知JVM进行垃圾回收?

     由于垃圾回收器的存在,Java语言本身没有给开发人员提供显式释放已分配内存的方法,也就是说,开发人员不能实时地调用垃圾回收器对某个对象或所有对象进行垃圾回收。但开发人员却可以通过调用System.gc()方法来“通知”垃圾回收器运行,当然,JVM也并不会保证垃圾回收器马上就会运行。由于System.gc()方法的执行会停止所有响应,去检查内存中是否有可回收的对象,这会对程序的正常运行以及性能造成极大的威胁,因此实际编程时,不推荐频繁使用这一方法。

参考:https://www.cnblogs.com/ghoster/p/7580729.html

还可以看:https://mp.weixin.qq.com/s/Pj0HHwHG5NJhduYOf6R8xQ

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值