3. JVM GC算法及具体垃圾收集器( 二 )


3.4.4记忆集和卡表
卡表是记忆集的具体实现之一
为了解决跨代引用问题在新生代中维护记忆集来避免对整个老年代扫描 。
记忆集的精度
3.4.5写屏障
解决怎么去维护记忆集的问题,通过写屏障(Write ) 。
写屏障可理解你额为AOP,虚拟机对引用类型复制就是整个切面,写屏障在这些对象赋值指令前后产生一个唤醒通知,供程序做额外动作 。
3.4.6 并发的可达性分析
GC Roots通过等优化时间段所以SWT 而并发标记阶段则占用大量时间不能STW 所以需要和用户程序一起执行,通过三色标记(Tri-color )来保障一致性 。
三色标记解决的问题:由于和用户线程并发执行导致对象引用变更,若改回收的对象标记为黑色那还好,等待下一次回收即可
但不该回收对象被标记为白色则会导致程序出错
两个将黑色对象错误的标记为白色的必要条件
赋值器插入了一条或多条黑色到白色对象的引用赋值器删除了全部灰色对象到该白色对象的直接或间接引用
为了破坏这两个条件产生了两种方案
增量更新( )
黑色对象一旦新插入了对白色对象的引用变回灰色对象需要从他开始重新扫描,类似MVCC 与乐观锁,加入对象变更导致重要数据变化需要重新扫描
原始快照( at the ,STAB)
下引用删除时记录这些对象,将其置为灰色重新扫描
两种都类似乐观锁思路是在对象发生某一点的变更时记录并重新扫描
CMS 增量更新
G1原始快照
3.5经典垃圾收集器
垃圾收集器是垃圾收集算法的实现
3.5. 会产生长时间STW简单,不会产生并发问题
在微服务场景下为每个服务分配的内存不会很多在不频繁收集的情况下可能也不错
3.5.2 收集器
的多线程版本
能与CMS收集器配合
-XX:+ 激活+CMS
-XX:+/- 指定/禁用
JDK9取消+ Old / +CMS
XX: 限制收集线程数
·并行():并行描述的是多条垃圾收集器线程之间的关系,说明同一时间有多条这样的线程在协同工作,通常默认此时用户线程是处于等待状态 。·并发():并发描述的是垃圾收集器线程与用户线程之间的关系,说明同一时间垃圾收集器线程与用户线程都在运行 。由于用户线程并未被冻结,所以程序仍然能响应服务请求,但由于垃圾收集器线程占用了一部分系统资源,此时应用程序的处理的吞吐量将受到一定影响 。
并行指多个GC线程互相合作,在多线程场景下也可能是并发
这里的并发语义指GC线程与用户线程的运行情况,是交替运行还是暂停用户线程只允许GC线程
3.5.3
与CMS对比
如果读者对于收集器运作不太了解,手工优化存在困难的话,使用 收集器配合自适应调节策略,把内存管理的调优任务交给虚拟机去完成也许是一个很不错的选择 。只需要把基本的内存数据设置好(如-Xmx设置最大堆),然后使用-XX:参数(更关注最大停顿时间)或-XX:(更关注吞吐量)参数给虚拟机设立一个优化目标,那具体细节参数的调节工作就由虚拟机完成了 。自适应调节策略也是 收集器区别于收集器的一个重要特性 。
PS+PO
实际上不管如何,/ 都是需要STW的,区别在于单线程还是多线程收集,或者说关注收集细节,但实质上还是STW
CMS关注停顿,而PS关注吞吐量(用户代码运行时间/(用户代码运行+GC时间))
用 户 代 码 运 行 时 间 用 户 代 码 运 行 时 间 + G C 时 间 \frac{用户代码运行时间}{用户代码运行时间+GC时间} 用户代码运行时间+GC时间用户代码运行时间?
可自适应调节 。