对象在年轻代移动过程
对象→Eden区→m
新生代收集器:
- seiel收集器:单核处理器最优。垃圾收集运行时候stop the world 只有垃圾收集器线程运行,其他线程处于安全点,也就是在内核态。垃圾收集器处于用户态。
- parNew收集器:除了多线程,其他和seiel一模一样。
- parllar scanvege: 标记复制算法。关注吞吐量,达成控制吞吐量的垃圾收集器。吞吐量= 运行时间/(运行时间+垃圾收集时间)
涉及参数: 吞吐量,最大垃圾收集时间。
怎么处理:多次运行mina GC,到时间就停止。
老年代垃圾收集器:
- seiel old收集器:标记整理算法
- parllar old收集器:JDK1.6 提供,多线程标记整理,不是重点,用得少,搞吞吐量的。
- CMS收集器:多线程标记清除收集器,目标是最短停顿时间。重点。
标记和清除过程:
初始标记:停顿,看GCroot关联到的对象
并发标记:不停顿,标记
重新标记:停顿,重新标记
并发清除:不停顿
cms:
四步,3个mark(初始,并发,重新)一个清除
初始标记和重新标记需要停顿(stw)
缺点1:cms对占用资源敏感
cms默认(处理器核数+3)/4
假如4核 (4+3 )/4
20核(20+3)/4
核数越多
缺点2:没办法处理浮动垃圾
并发清除时产生的垃圾没法标记,就没法清除
缺点3:标记清除算法,会有空间碎片
根节点枚举:垃圾收集标记阶段,需要寻找GC ROOT,都需要stop the world,否则一边标记,一边产生新垃圾,永远处理不完,用户线程停止的点在jvm安全点上。
安全点:安全点位置的选取基本上是以“是否具有让程序长时 间执行的特征”为标准进行选定的。
“长时间执行”的最明显特征就是指令序列的复用,例如方法调用、循环跳转、异常跳转等都属于 指令序列复用,所以只有具有这些功能的指令才会产生安全点。
G1
分块Region
- G1不再坚持固定 大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间。
- 收集器能够对扮演不同角色 的Region采用不同的策略去处理,这样无论是新创建的对象还是已经存活了一段时间、熬过多次收集的旧对象都 能获取很好的收集效果。
- Region中还有一类特殊的Humongous区域,专门用来存储大对象。
G1认为只要大小超过了一个Region容量一半 的对象即可判定为大对象。
每个Region的大小可以通过参数-XX:G1HeapRegionSize设定,取值范围为1MB~ 32MB,且应为2的N次幂。而对于那些超过了整个Region容量的超级大对象,将会被存放在N个连续的 Humongous Region之中,G1的大多数行为都把Humongous Region作为老年代的一部分来进行看待。
初始标记,并发标记,最终标记,筛选回收(时间可预测,选择回收)