垃圾收集器介绍
垃圾收集器:
引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用时。计数器值就增加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。
注:很难解决java问题中的对象之间的相互循环引用问题。
根搜索算法: 通过一系列的名为“”GC Roots”的对象为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots 没有任何的引用链相连时,
则证明此对象是不可用的。
注:GC Roots对象分为:(1)虚拟机栈(栈帧中的本地变量表)中的引用的对象。
(2)方法区中的静态属性引用的对象。
(3)方法区中常量引用的对象。
(4)本地方法栈中JNI(native方法)的引用的对象。
引用:引用数据类型的值存储的是一块内存的起始地址,则代表着一种引用。
Java中将引用分为:强引用、软引用、弱引用、虚引用。
强引用:只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。
软引用:系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中并进行第二次回收。
弱引用:被弱引用关联的对象只能生存到下一次垃圾收集器发生之前。
虚引用:一个对象是否有虚引用的存在,完全不影响其生存时间,也无法通过虚引用来取得一个对象实例。
方法区回收(永久代回收):废弃常量和无用的类。
废弃常量:当前系统没有任何地方引用这个常量,如果发生内存回收,有必要的话,会被系统清除常量池。
无用的类:(1)该类所有的实例都已经被回收,Java堆中不存在该类的任何实例。
(2)加载该类的ClassLoader已经被回收。
(3)该类的Java.lang.Class对象没有在任何地方被引用,无法通过反射访问该类的方法。
垃圾收集算法: (1)标记-清除算法(最基础):分为标记和清除两个阶段,首先是标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象。
缺点:(1)效率不高;
(2)空间问题:标记清除后,会产生大量不连续的内存碎片,可能会导致以后的程序需要分配较大对象时,无法找到足够的连续内存,
而触发垃圾收集动作。
(2)复制算法:它将可用内存按容量分为了大小相等的两块,每次只使用其中的一块。当这一块的内存用完后,就将还存活着的对象复制到另一块上去,
然后再把已使用的内存空间一次清理掉。
(3)标记-整理算法:标记过程与标记-清除算法中的标记一样,然后让所有存活对象都向一端移动,最后直接清理端边界以外的内存。
(4)分代收集算法:当代商业虚拟机都采用 “分代收集” 算法,根据对象的存活周期的不同将内存划分为几块。将java堆分为新生代和老年代,然后就可以根据各个年代
的特点采用最适当的收集算法。
在新生代中,有大批的对象死亡,只有少数存活,采用复制算法;
在老年代中,对象存活率较高,故采用标记-清除或标记-整理算法。
垃圾收集器分类:
Serial收集器 :在JDK1.3之前是虚拟机新生代收集的唯一选择,这个收集器是最基础的、最悠久的收集器,这个收集器是单线程收集器。
Serial垃圾收集器在进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。