标记革除算法
当堆中的无效空间被耗尽时,JVM就会进行整个程序(也被称为stop the world),而后开始两项工作.一是:标记
, 而是:革除
标记
遍历所有GC Roots,将所有GC Roots可达的对象都标记为存活对象.
革除
遍历堆中所有的对象把没有标记的对象全副革除.
在程序运行期间,当堆中的可用内存被耗尽时,GC线程就会启动并进行程序,GC线程将存活的对象标记一遍,没有被标记的对象就是垃圾对象,最初这些垃圾对象会被革除掉,而后从新唤醒应用程序.
程序运行时堆中对象的状态(默认为0未标记,1为标记过),如果堆内存的可用空间被耗费完,那么GC线程就会启动,进行掉应用程序,应用根可达性算法进行搜寻标记.
被标记后的对象状态
应用根可达性算法,所有GC Roots可达的对象都被标记为存活对象,此时曾经实现了第一阶段的工作.接下来执行革除操作,执行完革除操作,堆中对象的状态.
没有标记的对象被革除,被标记的对象会被留下,标记为被置为0,应用程序被唤醒.
标记革除的长处是算法简略,毛病如下:
1.效率低下,须要遍历整个堆.进行GC的时候须要进行应用程序
2.垃圾回收后的内存空间是不间断的,因为垃圾对象的散布很随便,那么革除后的内存会不间断. 为了解决这个问题,JVM不得不保护一个闲暇链表,又会导致额定的开销.
复制算法
复制算法应用了两块等同大小的内存空间,每次只用一块,垃圾回收的时候,把存活的对象间接另外一块内存,而后残余的垃圾对象全副一次性革除.益处是复制存活对象的时候就不必思考内存碎片.惟一的毛病就是内存利用率只有50%.
当初的虚拟机个别都用复制算法回收新生代,IBM的钻研发现,新生代中的对象98%都是朝生夕死,所以并不需要1:1调配对象,而是将内存分为一个大的Eden和两块小的Survivor空间,每次只应用Eden和一块Survivor. 当进行垃圾回收时,将存活对象一次性复制到一块Survivor空间,最初革除掉Eden和应用过的Survivor空间. HotSpot虚拟机Eden:Survivor=8:1,也就新生代可用的内存达到90%,只会有10%的节约.当然98%的对象可被回收只是个别的场景,并没有方法保障每次Survivor都能寄存的下存活对象,若Survivor空间不够时,须要依附老年代进行调配担保.
from ,to为Survivor区。