1.serial单线程,新生代用复制算法,老年代使用标记整理算法。
2.parallel是serial的多线程版本。
3.cms是新生代复制,老年代用标记清除,清除后还不够用才启动整理。
4.g1则继承了cms的低停顿的好处的前提下,尽量规避它碎片化的坏处。分区域,老年代和新生代都在它分区域的统筹之内。新生代的块还是类似复制算法,清理的很快,老年代的块当中垃圾最多的,会在回收后把剩余的数据压缩并移动到其他块里,其实跟新生代的复制很类似,然后清除该块,这样用最小代价获得可用空间。
5.总结,不管是哪种收集器,包括g1在内,发生fullgc时都是要整理全部堆内存,停顿时间会很长,所以一定要减少fullgc
三色标记法
1.初始标记:gcroots标记为灰色,然后遍历灰色的,改为黑色,并将直接引用的标记成灰色。就到这。如果不考虑具体实现,gc策略的接下来都希望继续这样遍历标记,一直到全部黑色和白色,没有灰色,然后就清掉白色。
2.但是如果一直理想化的标记,那得一直stw才行,这无法接受。所以要想办法并行gc,因为经过统计,初始标记的结果,经过一段时间的运行可能绝大多数对象引用关系没变。所以可以跟用户线程并行执行,继续标记。但是要把用户线程运行导致的变化记录下来,最后来个重新标记,查漏补缺。
3.用户线程可能导致的变动:比如一个没扫过的对象默认是白色的,不知道该不该清除,很可能是不该的,但是它断开了与所有灰色的连接,改成了与黑色连接。由于黑色的不会再扫了,所以白色永远没机会变黑色。所以可能应该保留的被清除了。
4.cms的解法是针对白色与黑色建立连接的行为,记录到cardtable里,把这个黑色对象置为灰色,这样就能扫描它引用的对象了(刚才那个白色的)。可以解决,但是remark需要扫的就比较多,比较慢。
5.g1的解法是针对白色与全部灰色断开连接的行为。。。