GC四大内存回收算法

    • 新生代
      • Eden 伊甸园
      • Survivor 存活区
      • Tenured Gen 退休区
    • 老年代
  • 方法区
  • 栈,本地方法栈 程序计数器

1、标记清除法
GC四大内存回收算法_第1张图片
根据被标记的垃圾对象,逐个进行清理。效率高,但是清理回收后,导致内存不连续,形成内存碎片。此时如果有新对象需要消耗更大的内存,虽然总空闲内存足够,由于内存不连续,会导致创建失败。为了解决这个缺陷,故而衍生了下面的复制法。
2、复制法
GC四大内存回收算法_第2张图片
GC四大内存回收算法_第3张图片
将可用的内存按容量划分为大小相等的两块(from,to)。每次把没有被标志的,即幸存的对象复制到一边去(to),然后把(from)这块内存格式化的清理。这样子就能保证被清理的内存总是连续可用的。然而,每次只是用其中一块(总有一块是空的【to区域】),造成了内存的使用率折半。
针对内存使用率问题底下,复制算法又继续衍生出下面的不均分的三块内存区,其中Eden区占据最大
GC四大内存回收算法_第4张图片
第二次GC:
GC四大内存回收算法_第5张图片
新生代的幸存区(Survivor)保持的是上一次Eden区中被保留的对象和上一次另一个Survivor副本里面保留的对象。两个Survivor区做常规的复制算法,Eden区与当前被选为备份的Survivor区做复制算法。Eden区是新生代最开始的一个区域,每次GC光顾后,10%的对象是存活的,把这10%的对象复制后,清空Eden区,重新得到大块的Eden可用内存。故而内存的使用率由50%提高到了80%,
但是对于幸存区(survivor),90%都是仍然存活的,那么每次都要去遍寻复制会造成性能的浪费。
3、标记整理法
标记:
GC四大内存回收算法_第6张图片

整理:把被标记的垃圾对象移动到内存的末端,统一回收。
GC四大内存回收算法_第7张图片
标记整理算法主要是针对Survivor区内存回收的,它的“标记”过程和标记-清除算法一致,只是后面并不是直接对可回收对象进行整理,而是让所有垃圾对象都向末端移动,然后直接清理掉端边界意外的内存。由于标记后继续整理,可以很明显的看出未使用的地址空间都是连续的,不会产生内存碎片。而且不需要复制幸存对象,针对Survivor区,大量对象都是幸存的,可以有效避免重复的复制工作导致性能的浪费。
4、分代收集法
其实分代收集法并不是一个新的算法,只是整合了复制算法和标记整理算法,管理它们。针对不同的内存区域,根据这些内存区域的特性使用不同的算法(选择复制法还是标记整理法)。例如,在新生代中的Eden区,对象的存活率是非常低的,这里被采用复制算法;在老年代内存区,存活率超级高,这里会采用标记整理算法。
以上是本人对GC各收集算法的浅薄理解,没有经过强有力的论证,有不足之处还望多多指教!

你可能感兴趣的:(jvm)