参考资料
https://plumbr.io/handbook/garbage-collection-algorithms-implementations
https://www.cnblogs.com/czwbig/p/11127159.html
Minor GC
平平无奇。参考Serial和Parallel即可。
Full GC
CMS的full gc只回收老年代,分为了7步。
Phase 1: Initial Mark. This is one of the two stop-the-world events during CMS. The goal of this phase is to mark all the objects in the Old Generation that are either direct GC roots or are referenced from some live object in the Young Generation. The latter is important since the Old Generation is collected separately.
第一步:Initial Mark。 从GC root开始,查找到被GC root直接引用或者被young区直接引用的老年代对象。标记上。这个过程需要stop the world。
Phase 2: Concurrent Mark. During this phase the Garbage Collector traverses the Old Generation and marks all live objects, starting from the roots found in the previous phase of “Initial Mark”. The “Concurrent Mark” phase, as its name suggests, runs concurrently with your application and does not stop the application threads. Note that not all the live objects in the Old Generation may be marked, since the application is mutating references during the marking.
第二步:Concurrent Mark。 这个过程与应用程序并发运行(不stop the world),已第一步找到的对象为起点,向下遍历引用的对象。标记上。
Phase 3: Concurrent Preclean. This is again a concurrent phase, running in parallel with the application threads, not stopping them. While the previous phase was running concurrently with the application, some references were changed. Whenever that happens, the JVM marks the area of the heap (called “Card”) that contains the mutated object as “dirty” (this is known as Card Marking).
第三步:Concurrent Preclean。由于第二步没有stop the world,有可能出现标记完后,对象引用被修改:第二步标记的对象已经没人引用了;第二步没标记到的对象被引用了。第三步的主要作用是处理这些有修改的情况。第三步不stop the world。Card Mark机制能让JVM发现在第二步完成后被改过的card。第三步的工作是在这些card中向下遍历引用对象,标记上。
Phase 4: Concurrent Abortable Preclean. Again, a concurrent phase that is not stopping the application’s threads. This one attempts to take as much work off the shoulders of the stop-the-world Final Remark as possible. The exact duration of this phase depends on a number of factors, since it iterates doing the same thing until one of the abortion conditions (such as the number of iterations, amount of useful work done, elapsed wall clock time, etc) is met.
第四步:Concurrent Abortable Preclean。第四步与第三步干的工作是一样的,但是第四步可中断(不中断的话,或许它可以永远干下去,因为内存的状态在不断变化)。中断的条件有多方面的考虑,比如遍历的深度,已经标记的对象数,已经消耗的时间,等等。
Phase 5: Final Remark. This is the second and last stop-the-world phase during the event. The goal of this stop-the-world phase is to finalize marking all live objects in the Old Generation. Since the previous preclean phases were concurrent, they may have been unable to keep up with the application’s mutating speeds. A stop-the-world pause is required to finish the ordeal.
Usually CMS tries to run final remark phase when Young Generation is as empty as possible in order to eliminate the possibility of several stop-the-world phases happening back-to-back.
第五步:Final Remark。 第五本需要stop the world。在前面几步的基础上,标记老年代中所有的活对象。
一般而言,CMS会尽量在young区对象尽可能为空的情况下执行Final Remark。避免Full GC之后很快又来个minor GC。这样两次stop the world(一次full gc,一次minor gc)就挨得太近了。
Phase 6: Concurrent Sweep. Performed concurrently with the application, without the need for the stop-the-world pauses. The purpose of the phase is to remove unused objects and to reclaim the space occupied by them for future use.
第6步:Concurrent Sweep。清除老年代中没有被标记的对象。不需要stop the world。
Phase 7: Concurrent Reset. Concurrently executed phase, resetting inner data structures of the CMS algorithm and preparing them for the next cycle.
第7步:重置相关的算法状态和数据结构。为下一次full gc做准备。
CMS的使用与问题
-XX:+UseConcMarkSweepGC开启CMS
默认在92%使用率时开始full GC, 通过修改来调整 XX:CMSInitiatingOccupancyFraction=N
CMS相关的jvm参数。
- -XX:+UseConcMarkSweepGC:激活CMS收集器。
- -XX:CMSInitiatingOccupancyFraction={x}:在老年代的空间被占用{x}%时,调用CMS算法对老年代进行垃圾回收。
- -XX:CMSFullGCsBeforeCompaction={x}:在进行了{x}次CMS算法之后,对老年代进行一次compaction(碎片整理)
- -XX:+CMSPermGenSweepingEnabled & -XX:+CMSClassUnloadingEnabled:让CMS默认遍历永久代(Perm区)
-
-XX:ParallelGCThreads: Sets the number of threads used during parallel phases of the garbage collectors. The default value varies with the platform on which the JVM is running. 并行阶段的线程数,如第一步和第五步。
-
-XX:ConcGCThreads: Number of threads concurrent garbage collectors will use. The default value varies with the platform on which the JVM is running. 并发阶段的线程数,如第二步和第三步。
- -XX:+ExplicitGCInvokesConcurrent:用户程序中可能出现利用System.gc()触发系统Full GC(将会stop-the-world),利用这个参数可以指定System.gc()直接调用CMS算法做GC。
- -XX:+DisableExplicitGC:该参数直接让JVM忽略用户程序中的System.gc()
具体参数的默认值使用java命令查看
java -XX:+printFlagsInitial