1.垃圾是指运行程序中没有任何指针引向的对象,如果不及时进行垃圾回收,内存会溢出
2.为什么要有GC
- 内存回收
- 整理内存碎片
- 保证程序正常运行
3.GC算法概述
标记阶段:区分对象是否存活
清除阶段:清除算法、
- 标记阶段->引用计数算法:
对每个对象保存一个整形的引用计数器属性,用于记录对象被引用的情况,引用+1,不引用-1
优点:实现简单,垃圾对象便于标识,判断效率高,回收没有延迟
缺点:它需要单独字段存储计数器,增加内存开销,需要更新计数器,时间开销
无法处理循环引用,致命缺点。导致java回收器没有使用此算法 - 标记阶段->可达性分析算法(跟踪性垃圾回收)
1)以跟对象集合(GC roots)为起始点,按照从上至下的方式搜索被跟集合对象所连接的目标是否可达
2)内存中存活对象都会被根对象集合直接或者间接引用,搜索所走的路径称为引用链(Reference Chain)
3)如果目标没有任何引用链,则不可达,即对象已死亡,可标为垃圾对象
GC ROOTS:虚拟机栈中引用的对象、本地方法栈引用对象、方法区中静态属性引用的对象、方法区总常量引用的对象、所有被同步锁synchronized持有的对象、java虚拟机内部的引用、JMXBean JVMTI注册的回调、本地代码缓存 - 清除算法(Mark sweep)
从Collector从引用根节点开始遍历,标记所有被引用的对象,在对象header记录为可达对象,从头到尾遍历,没有被标记的就会被清除
优点:常见
缺点:效率不高、得停止用户程序、会产生内存碎片,需要维护一个空闲列表 - 复制算法
将或者的内存分为两块,每次只使用一块,垃圾回收时将正在使用的存活的对象复制到未被使用的内存块,之后清除正在使用的内存块的所有对象,交换两个内存的角色 ,最后完成垃圾回收,用在年轻代suvivor区
优点:没有标记和清除过程,简单高效,不会出现内存碎片
缺点:需要两倍内存空间,开销大内存占用大
建立在成活对象少,垃圾对象多的情况下 - 标记 压缩(标记 整理)
用在老年代里,第一个阶段和清除算法一样标记所有引用对象,第二阶段将所有的存活对象压缩到内存的一短,清理边界外所有空间
优点:不会产生内存碎片、内存开销减少相比于复制算法
缺点:效率低于复制算法,移动对象时,如果被其他对象引用,还需要调整引用的地址,移动过程中,需要全程暂停用户程序
4.finalization
当垃圾回收器发现没有指针引向的对象时,总会先调用这个对象的finalize()方法,可以在子类重写,通常关闭文件、套接字、数据库连接会用到finalize
对象的图