java垃圾回收的一些简单知识
2016-06-11 16:18
429 查看
第一章 垃圾回收算法
1.1 标记-清除(Mark-Sweep)算法
概述:最基础的垃圾收集算法,后续的垃圾收集算法都是改进此算法的结果。过程:先标记,后清除。
不足:(1)效率问题,标记和清除两个阶段的效率都不高;(2)空间问题,标记清除后会产生大量的空间碎片,分配大对象的时候会因为空间限制而不得不提前触发一次垃圾收集动作。
1.2 复制算法
概述:解决了标记清除算法的效率问题,多用在商业虚拟机的新生代,老年代基本不用。过程:将内存划分为大小相等的两块,当一块用完的时候就将还存活的对象复制到另一块,然后将已经使用过的空间一次性全部清理掉。
优点:每次只回收整个半区,实现简单,运行高效,不需要考虑内存碎片等问题。
不足:内存缩小为原来的一半。
1.3 标记-整理(Mark-Compact)算法
概述:多用在对象存活率较高的区域,多用在老年代。过程:类似于标记-清除算法,但是后续步骤不是直接回收,而是让存活的对象都向一端移动,直接清理掉端边界以外的内存。
优点:解决复制算法的缺点,避免对象存活率较高时的多次回收。
1.4 分代收集(Generational Collection)算法
概述:根据对象的存活周期不同将内存划分为几块,java堆一般划分为新生代和老年代,新生代中的对象存活率较低,适合用复制算法;老年代中的对象存活率较高,而且没有额外的空间对它进行担保,必须使用标记-清除算法或者标记-整理算法。第二章 垃圾收集器
2.1 概述
如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。到目前为止还没有最好的垃圾收集器出现,我们只能根据具体应用场景选择最合适的垃圾收集器。如果两个垃圾收集器之间存在连线,就说明它们可以配合使用。
2.2 几种垃圾收集器
2.2.1 Serial收集器
概述:Serial收集器是最基本的,发展历史最悠久的收集器。单线程,必须“Stop-The World”。Serial主要运行在新生代,采用复制算法,Serial Old主要运行在老年代,采用标记-整理算法。优点:对于限定单个CPU的环境来说,Serial收集器没有线程交互的开销,简单高效。
不足:收集线程运行时必须暂停用户线程,用户体验不好。
2.2.3 ParNew收集器
概述:ParNew收集器是Serial收集器的多线程版。新生代多线程复制算法,老年代单线程标记-整理算法,-XX:ParallelCCThreads参数用于控制线程数量,默认与CPU核心数相同。优点:多线程,可以和CMS配合。
缺点:单CPU环境下效果绝不比Serial好。
2.2.4 ParallelScavenge收集器
概述:采用复制算法的新生代多线程收集器,专注于精确控制吞吐量。-XX:MaxGCMillis用于控制最大垃圾收集停顿时间,是大于0的毫秒数;-XX:GCTimeRatio参数用于控制吞吐量,是大于0小于100的整数,9d1c
吞吐量= 1 - (1 / (1 + x))(x为参数值,默认99)。
优点:停顿时间短,吞吐量可控,可通过-XX:UseAdaptiveSizePolicy参数来开启GC自适应调解策略。
缺点:在ParallelOld没出来之前只能和Serial Old配合使用,可选择的组合少。
2.2.5 Serial Old收集器
概述:Serial收集器的老年代版本,采用标记-整理算法。优点:给Client模式下的虚拟机使用,jdk1.5及之前版本可与Parallel Scavenge配合使用(效果不好,拖累Parallel Scavenge的吞吐量),或者作为CMS发生Concurrent Mode Failure时的后备方案。
2.2.6 Parallel Old收集器
概述:ParallelScavenge收集器的老年版,用于与Parallel Scavenge配合提高吞吐量。优点:可与ParallelScavenge配合,在注重吞吐量和CPU敏感的场合使用。
2.2.7 CMS(Concurrent MarkSweep)收集器
概述:以获取最短回收停顿时间为目标的收集器,主要应用于互联网站和B/S服务器端。运行过程:initial mark—>concurrent mark—>remark—>concurrent sweep。
Initial mark:STW,单线程;
Concurrent mark:可并发,单线程;
Remark:STW,多线程;
Concurrent sweep:可并发,单线程。
优点:系统停顿时间短,接近于并行执行,用户体验好。
不足:
(1)对CPU资源敏感:CPU核数越多性能越好,默认线程数为(CPU数+3)/4,4个CPU是分水岭。
(2)无法处理浮动垃圾:浮动垃圾是指标记过程之后出现的垃圾。可能出现“Concurrent Mode Failure”,导致采用Serial Old的后备方案启动,停顿时间长。
(3)由于采用标记-清除算法,会产生大量的碎片空间。
2.2.8 G1收集器
概述:G1是一款面向服务端应用的垃圾收集器,有希望替换掉CMS。运行原理:化整为零,建立region的优先列表,优先回收价值最大的region(体现Garbage-First)。
运行过程:initial marking—>Concurrentmarking—>final marking—>Live data counting and evacuation。
Initial marking:STW,单线程;
Concurrent marking:可并发,单线程;
Final marking:STW,多线程;
Live data counting and evacuation:STW,多线程。
优点:
(1)并行与并发;
(2)空间整合:G1从总体上看是基于标记-整理算法,从局部(两个region之间)来看是基于复制算法,没有空间碎片,内存规整;
(3)可预测的停顿:能够让使用者明确指定在M毫秒内,消耗在垃圾收集上的时间不得超过N毫秒。
不足:未经实践检验,存在不确定性。
态度:如果你现在采用的垃圾收集器没有出现问题,那就没有任何理由现在去选择G1,如果你的应用追求低停顿,可以尝试G1,如果你的应用追求吞吐量,那么G1不会为你带来什么好处。
相关文章推荐
- JAVA学习总结十五
- [Java]Session,Cookie知识与应用
- JavaWeb学习笔记之Servlet九大内置对象
- 三大框架-------->struts2 OGNL表达式
- leetcode-java-198. House Robber
- JavaWeb学习笔记之Mybatis关键对象
- Spring源码阅读之Resource接口
- Spring中出现The prefix “xxxx” for element “xxxxxx”is not bound.即一些标签不提示而且你又找不到dtd约束文件
- Ubuntu 15.04 下apt-get安装JDK
- Spring提供的单元测试
- leetcode 113. Path Sum II-路径和|回溯算法
- (转)java 从jar包中读取资源文件
- java的常见异常与错误总结
- Hibernate4关系映射总结
- 深入理解Java国际化
- Java---俄罗斯方块小游戏
- Java---俄罗斯方块小游戏
- 国际化: 理解Java平台上的Locale
- 增强型for循环
- java 时间戳