JAVA的垃圾收集器与内存分配策略【一篇文章直接看懂】( 四 )


三色标记法:
–>由此总结出了产生对象消失问题的两条结论:
赋值器插入了一条或多条从黑色对象到白色对象的新引用;赋值器删除了全部从灰色对象到该白色对象的直接或间接引用 。
解决方案:
增量更新( ,破坏第一条):黑色对象一旦新插入了指向白色对象的引用之后,它就变回灰色对象了 。【新增白色引用时,记录该引用,扫描结束后,以该引用的黑色为根扫描】原始快照(Snap At The ,SATB,破坏第二条):无论引用关系删除与否,都会按照刚刚开始扫描那一刻的对象图快照来进行搜索 。【删除白色引用时,记录该引用,扫描结束后,以该引用的灰色为根重新扫描】
以上记录操作都是通过写屏障来实现的
经典垃圾收集器
链接的线指代两个收集器可以搭配使用 。
== 不存在“万能”的收集器,只有对具体应用场景更合适的收集器==
收集器(标记-复制算法)
该收集器是一个单线程工作的收集器,在进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束 。
迄今为止,它依然是虚拟机运行在客户端模式下的默认新生代收集器,有着优于其他收集器的地方,那就是简单而高效(与其他收集器的单线程相比)
1.是所有收集器里额外内存消耗( )最小的
2. 对于单核/处理器较少的环境,因为没有线程交互的开销,所以可以获得最高的单线程效率
在部分微服务中,内存一般不会特别大,所以垃圾收集的停顿时间也很短
收集器(标记-复制算法)
是收集器的并行版本,除了能并行其他与收集器完全一致 。
/ Old收集过程:
目前的用处:在JDK7之前遗留的系统中,只有他能与CMS(过去可以实现GC线程与用户线程同时工作的收集器)搭配使用,但是CMS作为老年代的无法与新生代的 搭配使用了,只有能搭配使用 。后续也被G1收集器所代替 。
·并行():并行描述的是多条垃圾收集器线程之间的关系,说明同一时间有多条这样的线程在协同工作,通常默认此时用户线程是处于等待状态 。
·并发():并发描述的是垃圾收集器线程与用户线程之间的关系,说明同一时间垃圾收集器线程与用户线程都在运行,但不一定是并行的,可能会交替运行 。由于用户线程并未被冻结,所以程序仍然能响应服务请求,但由于垃圾收集器线程占用了一部分系统资源,此时应用程序的处理的吞吐量将受到一定影响 。
收集器(标记-复制算法)
达到一个可控制的吞吐量()
吞吐量 = 运行用户代码时间 运行用户代码时间 + 运行垃圾收集时间 吞吐量 = \frac { 运行用户代码时间 } { 运行用户代码时间+运行垃圾收集时间 } 吞吐量=运行用户代码时间+运行垃圾收集时间运行用户代码时间?
停顿时间越短,越适合交互频繁的程序,高吞吐量可以最高效率地利用处理器资源,适合在后台运算而不需要太多交互的分析任务
用于控制吞吐量的参数:
-XX::最大垃圾收集停顿时间-XX::直接设置吞吐量大小-XX:y:激活后不需要人工指定细节参数,通过运行情况动态调整,称为自适应的调节策略(GC )
自适应调节策略也是 收集器区别于收集器的一个重要特性 。
以上皆为新生代收集器
Old收集器(标记-整理算法)
单线程收集器,主要提供给客户端模式下的虚拟机使用,在服务端模式下,作为CMS的后备方案
Old收集器(标记-整理算法)
的老年代版本,在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先考虑 加 Old收集器这个组合