基于1.7
垃圾回收算法
- 标记-清除
先对需要回收的进行标记而后对可回收对象进行清除,
缺点:会造成空间不连续 - 复制
将内存分为若干份,先使用一块儿,若当前空间不足触发垃圾回收,将当前空间的存活对象复制到另一份,把已使用的内存空间一次清理掉。造成了内存的浪费。所以Hotspot设计将内存分为一块较大的eden和两块较小的fromsurvivor、tosurvivor。minor gc后将eden存活的对象复制到未使用的to,fromsurvivor够老的进入老年代,不够老的复制到to,如果to survivor空间不足以容纳则通过分配担保机制进入老年代。minor gc之后 from 和to交换角色,如下图的b。
默认eden与survivor的比例为8:1:1。
- 标记-整理
先对需要回收的进行标记而后让存活的对象向一端移动,然后直接清理掉端边界以外的内存、 - 分代收集算法
将内存划分为几块,比如划分为新生代、老年代,然后根据各个年代的特点采用适当的收集算法
垃圾收集器
- 垃圾收集器组合
横线上为年轻代收集算法,横线下为老年代收集算法。两个连线的垃圾收集器表示可以组合使用。G1见下文
- 垃圾收集器简介
收集器 | 算法 | 优缺点 | 新老代 |
---|---|---|---|
Serial | 复制 | 单线程收集,运行在client模式下默认的新生代收集器 | 新 |
ParNew | 复制 | serial的多线程版本 | 新 |
Parallel Scavenge | 复制 | 吞吐量优先,高效利用cpu适合后台运算任务 | 新 |
serial Old | 标记-整理 | 单线程收集,client模式默认老年代收集器 | 老 |
Parallel Old | 标记-整理 | 吞吐量及cpu敏感使用 | 老 |
CMS | 标记-清除 | 用户交互使用 | 老 |
- Parallel Scavenge
吞吐量=用户代码运行时间/(用户代码运行时间+垃圾收集时间),即垃圾收集时间越短,吞吐量越大。server模式下默认新生代垃圾收集器
-XX:MaxGCPauseMillis : 控制最大垃圾收集停顿时间
-XX:GCTimeRatio:吞吐量大小设置,大于0且小于100的整数 - CMS 收集器
- 收集过程分4个步骤:
初始标记(stop-the-world),标记GCRoots能直接关联的对象
并发标记,GCRoots Tracing,与用户线程一起工作
重新标记(stop-the-world),修改并发标记期间用户程序运作导致标记变动的对象的标记记录
并发清除,与用户线程一起工作 - cpu敏感型,默认启动的线程数=(cpu数+3)/4
- 浮动垃圾
并发清理阶段用户线程还在运行,会产生新的垃圾,cms在当次收集中无法回收。垃圾收集阶段用户线程还在运行,需要预留内存空间给用户线程使用,若在cms收集期间,预留的内存无法满足程序需要,会出现"concurrent mode failure"失败,失败之后会临时启用Serial Old收集器重新进行老年代的垃圾收集。-XX:CMSInitiatingOccupancyFraction设置老年代已使用比例激活cms收集的阈值 - 碎片
cms使用的标记-清除算法,会有大量空间碎片产生,会出现空间有剩余,但无法找到足够的连续空间分配对象,从而触发full gc
-XX:UseCMSCompactAtFullCollection : 默认开启,出现上述问题进行full gc时开启内存碎片的合并整理,无法并发,停顿时间变长
-XX:CMSFullGCsBeforeCompaction :执行多少次不压缩的full gc后进行一次压缩的full gc。默认0,每次都进行碎片整理。
- 收集过程分4个步骤:
相关参数
以-XX开头的是非稳定参数
参数 | 作用 | 使用场景 |
---|---|---|
-XX:UseAdaptiveSizePolicy | 打开之后,设置好-Xmx之后虚拟机自适应调整各个区的比例大小 | Parallel Scavenge |
-Xms | 堆大小的最小值 | |
-Xmx | 堆大小的最大值 | |
-Xmn | 新生代大小 | |
-XX:SurvivorRatio | 配置eden与surivivor比例 | |
-XX:PretenureSizeThreshold | 晋升老年代年龄,默认15 |