垃圾回收的目的:
把内存中过期(用不到)的对象清理,重新用来初始化新的对象。
垃圾回收的过程:
1.标记回收的对象
2.清理
3.整理碎片
标记的算法:
1。引数计数法。
每个对象被引用一次就加一,引用释放就减一,如果引用为0就可以被清理了。
特点:方法简单,但是不能解决相互引用的问题。
2。root可达性算法。
从GCroots向下搜索,不能被搜索到的对象为不可达对象,可以被清理
GCroots包括:
虚拟机栈引用的对象
方法区中类静态属性实体的引用对象
方法区中常量引用的对象
本地方法区JNI引用的对象
垃圾回收算法:
标记-清除
分两步,先标记出需要清理的对象,然后统一清除。
特点:效率不高,回收完成之后的内存空间不连续,碎块化。
复制算法:
把内存区域分成大小相同的(A/B)两个,使用的A区内存满了之后,遍历出存活的对象复制到B区,启用B区,清理A区。如此反复循环。
特点:需要停止其他线程活动,需要2倍的内存空间
标记-整理
标记处存活的对象,然后把这些存活的对象往内存区域的一端移动,然后清理掉另一端的内存区域供新的对象使用
分代收集算法
根据对象存活周期的不同,将内存划分为几块区域。一般把java堆分为新生代和老年代。再根据每个区域的特点使用最适合的算法。
新生代使用复制算法,老年代使用标记整理算法
垃圾回收器:
serial
单线程收集器,gc的时候会停止一切用户线程。
算法:复制算法
ParNew
serial的多线程版本
算法:复制算法
Parallel Scavenge
关注的是垃圾回收的吞吐量,多线程的
算法:复制
serial old
单线程老年代的回收器
算法:新生代-复制算法,老年代-标记整理
Parallel old
老年代的垃圾回收器,对线程
算法:标记整理
CMS:concurrent mark swap
最短回收时间为目的的回收器,有碎片,需要配置fullgc的时候清理碎片。
过程:
初始标记,标记可以直接root到的对象,stop the word
并发标记,多线程标记整个堆内存
重复标记,标记并发标记之后产生的新的对象的变化,stop the word
并发清理,并发清理。
算法:标记-清理
G1
将整个堆划分为多个大小固定的内存区域,并跟踪各个区域里的垃圾堆积程度,后台维护一个优先列表,每次处理垃圾最多的区域。
算法:标记-整理