java gc回收算法

java gc回收算法,今天学习到的主要有以下几种:
1、引用计数法
引用计数法很简单,给每个对象分配额外分配一个域,当有引用指向这个对象时,引用计数器+1,当引用失效时,引用计数器减一。当应用计数为0时,则认为其失效,被垃圾回收。
这种算法有两个缺点:
(1)每次引用的关联和失效都设计加减操作,可能效率上会有所损耗。
(2)这也是最核心的问题,无法解决循环引用的问题。即a对象中有b对象的引用,b对象中有a对象的引用,而若此时ab对象的引用失效,ab对象内部仍然持有对方引用,ab的引用计数都不为0,而此时ab对象是应该被垃圾回收的。
在js和python等语言中貌似就是使用的这种垃圾回收方法。
2、标记清除法
这个方法涉及到如何判断对象是否有效,在标记清除法中引入了“可达”和“不可达”的概念。对象与对象之间,使用有向图的方式来表达对方是否持有自己的引用,若一个对象,由根节点出发遍历不能达到,则称这个对象不可达,即没有对象持有他的引用,即可被回收。
标记清除法分为两个阶段,标记和清楚阶段。
每个对象在被创建出来的时候,gc线程就在监视对象的地址,使用状况,而这个过程中,gc线程将各个对象之间的引用关系用有向图的方式建立联系,在标记阶段,gc线程通过有向图遍历、标记出不可达的节点,这些节点即为应该要被回收的对象。
清除阶段将标记阶段标记出来的对象回收掉。这样的方法可以很好的解决循环引用的问题,但是这种回收方式会产生大量的内存碎片。因为被标记出来的对象可能是分布在内存各个位置的,这样的回收使空出来的内存空间并不连续,形成内存碎片。
3、复制算法
复制算法最典型的使用场景就是jvm内存结构中,堆内存中的新生代空间了。
jvm内存结构中,heap区分为两部分,新生代和旧生代,新生代存放新建的对象和经历不多gc回收后存活下来的对象;旧生代存放多次gc回收后仍然存活下来的对象。
其中,对新生代对象的gc回收就是采用复制算法。
复制算法通过将要存活下来的对象复制到另一块内存中来保留存活对象,然后将原来内存全部清空,再将存活下来的在别的内存空间的对象复制回来。新生代中,当发生gc回收的时候,eden区中要存活的对象会被复制到survive区中没有被使用的一个区域,然后gc会将eden区和survivez区中正在被使用的区域全部清空,这样保证了垃圾的回收,又保证了内存的连续。
4、标记压缩法
在标记清除法中,我们提到了会产生内存碎片。标记压缩法就是为了解决这个问题产生的。同样分为标记过程和压缩过程。
标记过程同标记清除法一样,标记不可达对象。但是在清除之前,会把存活对象复制压缩到内存的一端,清除回收的时候回收掉除了边界以外的内存。这样保证了存活对象的连续性。
5、分区算法
在垃圾回收过程中,程序处于暂停状态,也就是说垃圾回收的时间如果过长,可能导致程序运行的卡顿和不流畅。为了解决这种问题,我们将一次垃圾回收,分解成多次垃圾回收,减少回收时的消耗,可减少这种影响。具体实现就是通过分区算法,将一整块的内存空间分区为多块,每块独立运行自己的垃圾回收。即一整块内存区间的垃圾回收,被分为了多个区间的垃圾回收,从而减小了每一次垃圾回收对程序运行的影响。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值