java垃圾回收机制的三种回收算法图解
这块内容需要多画图理解
JVM内存中有五大模块:堆,方法区,栈,本地方法栈,程序计数器。而垃圾回收机制只存在于堆和方法区中,且绝大部分在堆中。
由于栈会弹栈,栈里面的数据会随着程序结束而出栈,故不存在垃圾。而程序计数器用于记录线程执行的行号,以确保线程切换后能记住当前线程执行的位置,因此也不存在垃圾。
所以我们探究的重点在于“堆”
下面来看看堆的内存结构
堆内存分为两个区——新生代区和老年代区。其中新生代区分为伊甸园区与幸存区。幸存区里是from和to区,两者是互相轮动变化的。
在幸存区没有放满对象时,垃圾回收属于轻GC,否则属于重GC。对于经历了15次(默认可调)GC的对象会进入老年代。如果老年代也满了,就会出现OOM错误(堆内存溢出)
在为堆的各内存区分配空间时,默认 (可调) 新生代:老年代=1:2;伊甸园:from:to=8:1:1
下面具体看三种回收算法
-
复制算法
from与to是轮动变化的,对伊甸园GC后。伊甸园的对象被清理了,而from的对象轮换到to里面,此时to变为from,原来的from变为to。以后每一次清理都会按照这个规律变化。清理后,伊甸园与to区都是空的。浪费了空间(内存利用率低),节省了时间。内存排列整齐。 -
标记清除算法
需要标记次数与扫描标记记录。浪费时间,增加内存消耗(内存利用率较高),且内存程碎片化排列,内存排列不整齐。
3.标记压缩算法
在标记清除算法的基础上在对不整齐的对象进行规整。浪费时间,增加内存消耗(内存利用率较高)。内存排列整齐
算法适用区域
新生代:存活率低——复制算法
老年代:存活率高——标记清除压缩混合实现(内存碎片少)