一、垃圾回收算法
垃圾回收算法分为垃圾收集算法和垃圾回收算法 1、垃圾收集算法: 1)、引用计数器算法: 有引用计数器+1,引用销毁的时候,计数器-1,当引用计数器=0时, 对象已经没有引用了,可以回收了! 弊端:相互引用形成一个环,则无法回收。 2)、根搜索算法(root节点算法、可达性分析算法) 从一个Root节点开始,寻找引用节点,剩余没有被引用的节点,则为无用节点,可以被回收。 扩展: JAVA引用分类: a)、强引用: 创建一个对象并把这个对象赋给一个引用变量,有引用变量指向时永远不会被垃圾回收; 例:Object obj = new Object(); obj对象对后面new Object的一个强引用 b)、软引用: 非必须引用,内存溢出之前进行回收;软引用主要用户实现类似缓存的功能; 例:Object obj = new Object(); SoftReference sf = new SoftReference(obj); sf是对obj的一个软引用 c)、弱引用: 当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象; d)、虚引用(幽灵/幻影引用): 每次垃圾回收的时候都会被回,主要用于检测对象是否已经从内存中删除。 每次垃圾回收的时候都会被回,主要用于检测对象是否已经从内存中删除。2、垃圾回收算法:
1)、标记-清除算法: 从根集合进行扫描,对存活的对象对象标记,标记完毕后,再扫描整个空间中未被标记的对象,进行回收 缺点:由于直接回收不存活的对象,会造成内存碎片 2)、复制算法: 从根集合扫描,并将存活对象复制到一块新的,没有使用过的空间中 缺点:需要一块内存交换空间用于进行对象的移动,成本高。 3)、标记-整理算法: 采用标记-清除算法一样的方式进行对象的标记,但在清除时不同,在回收不存活的对象占用的空间后, 会将所有的存活对象往左端空闲空间移动,并更新对应的指针; 缺点:造成内存碎片,且成本更高 4)、分代收集算法: 根据对象存活的生命周期将内存划分为若干个不同的区域,一般分为新生代(复制算法)和老年代(标记整理算法)二、常见的垃圾收集器
1、Serial收集器(复制算法):单线程的收集器。在进行垃圾收集时,必须暂停其他所有的工作线程,直到收集完成。 2、ParNew收集器:Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现。 3、Parallel Scavenge(并行回收)收集器: 新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器。可达到一个可控制的吞吐量。 主要适合在后台运算而不需要太多交互的任务。 4、Serial Old 收集器:Serial收集器的老年代版本,它同样是一个单线程收集器,使用标记整理算法 5、Parallel Old 收集器:是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法 6、CMS收集器:一种以获取最短回收停顿时间为目标的收集器, 步骤:初始标记(需要Stop The World,)、并发标记、重新标记(需要Stop The World,)、并发清除 优点:并发收集,低停顿 缺点:对CPU资源非常敏感;无法处理浮动垃圾;基于“标记-清除”算法实现的收集器,会有大量空间碎片产生 7、G1收集器:是一款面向服务端应用的垃圾收集器, 步骤:初始标记、并发标记、最终标记、筛选回收 优点:并行与并发,分代收集,空间整理 (标记整理算法,复制算法),可预测的停顿。jdk1.7 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)jdk1.8 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)jdk1.9 默认垃圾收集器G1复制代码