当堆中的有效空间被耗尽时,JVM就会中止整个程序(也被称为stop the world),而后开始两项工做.一是:标记
, 而是:清除
遍历全部GC Roots,将全部GC Roots可达的对象都标记为存活对象.
遍历堆中全部的对象把没有标记的对象所有清除.
在程序运行期间,当堆中的可用内存被耗尽时,GC线程就会启动并中止程序,GC线程将存活的对象标记一遍,没有被标记的对象就是垃圾对象,最后这些垃圾对象会被清除掉,而后从新唤醒应用程序.
程序运行时堆中对象的状态(默认为0未标记,1为标记过),假如堆内存的可用空间被消耗完,那么GC线程就会启动,中止掉应用程序,使用根可达性算法进行搜索标记.算法
被标记后的对象状态spa
使用根可达性算法,全部GC Roots可达的对象都被标记为存活对象,此时已经完成了第一阶段的工做.接下来执行清除操做,执行完清除操做,堆中对象的状态.线程
没有标记的对象被清除,被标记的对象会被留下,标志为被置为0,应用程序被唤醒.code
标记清除的优势是算法简单,缺点以下:对象
1.效率低下,须要遍历整个堆.进行GC的时候须要中止应用程序
2.垃圾回收后的内存空间是不连续的,由于垃圾对象的分布很随意,那么清除后的内存会不连续. 为了解决这个问题,JVM不得不维护一个空闲链表,又会致使额外的开销.blog
复制算法使用了两块同等大小的内存空间,每次只用一块,垃圾回收的时候,把存活的对象直接另一块内存,而后剩余的垃圾对象所有一次性清除.好处是复制存活对象的时候就不用考虑内存碎片.惟一的缺点就是内存利用率只有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区。内存