JVM - 垃圾回收器
Young GC
- 查找GC Roots,拷贝所引用的对象到to区
GC ROOTS内存区域主要包括- 线程栈空间中引用的对象
- 方法区中静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中JNI中引用对象
- 递归遍历步骤1中对象,并拷贝器所引用对象到to区,可能会存在自然晋升,或因为to区空间不足引起提前晋升。
GC年龄存在java对象头的markword字段,只占用4个bit,所以最大年龄是15。
默认到达15就会晋升到老年代!
CMS垃圾回收器(默认75%触发)
CMS回收器在一次GC过程中会有两次STW,一次是初始标记阶段,一次是重新标记阶段
- 初始标记(STW initial mark)- 用来标记从root直接可达的和从年轻代中对象直接可达的对象
- 并发标记 (Concurrent marking) - 遍历初始标记的存活对象,然后继续递归标记这些对象可达的对象
- 并发预清理(Concurrent precleaning) - 并发预清理用于减少remark的工作量,降低STW时间
- 重新标记(STW remark) - 用来标记在并发标记阶段遗漏的对象
- 并发清理(Concurrent sweeping) - 并发清理垃圾对象
- 并发重置 (Concurrent reset) - 并发清除内部状态,为下次回收做准备
G1垃圾回收器
G1堆内存结构
默认将JVM切分为2048份固定大小区域,最小1M,最大32M,2的幂次方;区域大小通过-XX:G1HeapRegionSize参数指定
G1堆内存分配
每块区域被标记了E、S、O和H,分别映射Eden、Survivor、老年代和巨型对象区
G1提供三种垃圾回收模式 young gc 、mixed gc 和full gc
- young gc - 年轻代gc算法,所有Eden region被耗尽无法申请内存时触发,执行完一次young gc,活跃对象拷贝到S区或晋升到old region,空闲region放入空闲列表,等待使用
参数 | 含义 |
---|---|
-XX:MaxGCPauseMillis | 设置G1收集过程目标时间,默认值200ms |
-XX:G1NewSizePercent | 新生代最小值,默认值5% |
-XX:G1MaxNewSizePercent | 新生代最大值,默认值60% |
-
mixed gc - 当越来越多对象晋升到old region时,为了避免内存耗尽,会触发mixed gc;回收整个young region 和部分old region,从而控制回收耗时时间,可以通过
-XX:InitiatingHeapOccupancyPercent 指定old region使用率百分比阈值,超过该阈值则直接触发,默认45%- 初始标记(STW initial mark)- 应用线程暂停,然后标记从root直接可达的对象
- 并发标记 - 该阶段耗时较长,但是可以与应用线程并发执行,遍历初始标记对象,继续递归标记这些对象可达的对象,采用STAB算法保证新分配对象不会漏标。
- 重新标记(STW) - 标记那些在并发标记阶段遗漏的对象
- 筛选回收 - 按照区域回收价值和成本进行排序,根据用户配置的GC停顿时间制定回收计划,开始回收部分区域
-
full gc - 对象内存分配速度过快,来不及进行mixed gc导致old region填满时触发;
该算法是单线程执行serial old gc,需要长时间STW,所以要尽可能避免full gc。
网友评论