JVM 垃圾收集算法思想

标记-清除算法

标记-清除(Mark-Sweep)算法是最基础的收集算法,算法分“标记”与“清除”两个阶段:首先标记处所有需要回收的对象,标记过程通过可达性算法确定对象是否死亡,死亡则标记,标记完所有死亡对象之后统一进行回收。

不足:

  • 效率低
  • 空间问题,标记清除后出现不连续内存碎片,在分配大对象时,无法找到足够的内存不得不再次触发GC动作。

在这里插入图片描述

复制算法

内存算法将内存划分为两个相等的内存块,每次只使用其中一块内存。当当前内存块使用完了,就会将当前内存快中存活的对象按照顺序复制到另外一块内存中,然后将当前内存空间一次性清理掉。这样使得每次都是对整个半区的内存进行回收清理,内存分配不需要考虑内存碎片的情况,只需要按照顺序分配即可。

不足:

  • 实际可用内存缩小为原来的一半

在这里插入图片描述

JVM采用分代布局进行堆内存管理,分为“新生代”与“老年代”以及“永久代”,平时我们所说的“永久代”更多指的是方法区。方法区的对象并不是所谓的“永久”存在,这部分内存区域的回收主要针对常量池的回收与类型的卸载,由于其回收条件的苛刻,通常该区域的内存回收情况并不乐观。
对于“新生代”,研究表明,新生代中的对象98%是“朝生夕死”的,所以并不需要按照1:1的比例来划分内存空间,而是将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次只使用Eden和其中一块Survivor。当内存回收时,将Eden和Survivor中幸存的对象一并复制到另外一块Survivor中,最后清理掉Eden和刚进行回收的Survivor空间。HotSpot虚拟机默认Eden与Survivor的比例为8:1,有百分之10的内存会被"浪费"。
上面所说98%的内存会被回收只是一般场景下的情况,没有办法保证每次回收存活的对象不会超过Survivor的内存大小(10%)。当Survivor空间不够时,需要依赖其他内存区域进行分配担保,也就是"老年代"的内存区域。如果另外一块Survivor空间没有足够内存存放新生代存活的对象,那么这些对象将会直接通过分配担保机制进入老年代。

标记-整理算法

复制收集算法如果在对象存活率较高的情况下,会进行较多的复制动作,效率会变低。在老年代中一般不会直接使用复制算法。
“标记-整理”(Mark-Compact)算法,标记过程仍然与"标记-清除"算法一样,但是后续不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉边界以外的内存。

在这里插入图片描述

分代收集算法

当前商用虚拟机的垃圾收集都采用“分代收集”算法。虚拟机一般会把JAVA堆分为新生代与老年代,这样就可以根据各个年代的特点采用最适合的收集算法。在新生代中每次垃圾收集都会发现大量的对象死亡,只有少量的存活,这种情况就选用复制算法,只需要复制少量的对象就可以完成收集。而老年代由于对象存活率高、没有额外的空间分配担保,就必须使用"标记-清理"或者“标记-整理”算法进行回收。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值