• GC: CMS垃圾回收器一(英文版)


    Memory Management in the Java HotSpot™ Virtual Machine

    Concurrent Mark-Sweep (CMS) Collector

    For many applications, end-to-end throughput is not as important as fast response time. Young generation
    collections do not typically cause long pauses. However, old generation collections, though infrequent, can
    impose long pauses, especially when large heaps are involved. To address this issue, the HotSpot JVM includes a
    collector called the concurrent mark-sweep (CMS) collector, also known as the low-latency collector.

    Young Generation Collection Using the CMS Collector
    The CMS collector collects the young generation in the same manner as the parallel collector.
    Old Generation Collection Using the CMS Collector
    Most of the collection of the old generation using the CMS collector is done concurrently with
    the execution of the application.
    A collection cycle for the CMS collector starts with a short pause, called the initial mark, that
    identifies the initial set of live objects directly reachable from the application code. Then,
    during the concurrent marking phase, the collector marks all live objects that are transitively
    reachable from this set. Because the application is running and updating reference fields while the
    marking phase is taking place, not all live objects are guaranteed to be marked at the end of the
    concurrent marking phase. To handle this, the application stops again for a second pause, called remark,
    which finalizes marking by revisiting any objects that were modified during the concurrent marking
    phase. Because the remark pause is more substantial than the initial mark, multiple threads are run in
    parallel to increase its efficiency.
    At the end of the remark phase, all live objects in the heap are guaranteed to have been marked, so the
    subsequent concurrent sweep phase reclaims all the garbage that has been identified. Figure 7
    illustrates the differences between old generation collection using the serial mark-sweep-compact
    collector and the CMS collector.

    Since some tasks, such as revisiting objects during the remark phase, increase the amount of work the
    collector has to do, its overhead increases as well. This is a typical trade-off for most collectors that
    attempt to reduce pause times.
    The CMS collector is the only collector that is non-compacting. That is, after it frees the space that was
    occupied by dead objects, it does not move the live objects to one end of the old generation. 

    This saves time, but since the free space is not contiguous, the collector can no longer use a simple
    pointer indicating the next free location into which the next object can be allocated. Instead, it now
    needs to employ free lists. That is, it creates some number of lists linking together unallocated regions
    of memory, and each time an object needs to be allocated, the appropriate list (based on the amount of
    memory needed) must be searched for a region large enough to hold the object As a result, allocations
    into the old generation are more expensive than they are with a simple bump-the-pointer technique.
    This also imposes extra overhead to young generation collections, as most allocations in the old
    generation occur when objects are promoted during young generation collections.
    Another disadvantage the CMS collector has is a requirement for larger heap sizes than the other
    collectors. Given that the application is allowed to run during the marking phase, it can continue to
    allocate memory, thereby potentially continuing to grow the old generation. Additionally, although the
    collector guarantees to identify all live objects during a marking phase, some objects may become
    garbage during that phase and they will not be reclaimed until the next old generation collection. Such
    objects are referred to as floating garbage.
    Finally, fragmentation may occur due to lack of compaction. To deal with fragmentation, the CMS
    collector tracks popular object sizes, estimates future demand, and may split or join free blocks to
    meet demand.

    Unlike the other collectors, the CMS collector does not start an old generation collection when the old
    generation becomes full. Instead, it attempts to start a collection early enough so that it can complete
    before that happens. Otherwise, the CMS collector reverts to the more time-consuming stop-the-world
    mark-sweep-compact algorithm used by the parallel and serial collectors. To avoid this, the CMS
    collector starts at a time based on statistics regarding previous collection times and how quickly the old
    generation becomes occupied. The CMS collector will also start a collection if the occupancy of the old
    generation exceeds something called the initiating occupancy. The value of the initiating occupancy is
    set by the command line option –XX:CMSInitiatingOccupancyFraction=n, where n is a
    percentage of the old generation size. The default is 68.
    In summary, compared to the parallel collector, the CMS collector decreases old generation pauses—
    sometimes dramatically—at the expense of slightly longer young generation pauses, some reduction in
    throughput, and extra heap size requirements.
    Incremental Mode
    The CMS collector can be used in a mode in which the concurrent phases are done incrementally. This
    mode is meant to lessen the impact of long concurrent phases by periodically stopping the concurrent
    phase to yield back processing to the application. The work done by the collector is divided into small
    chunks of time that are scheduled between young generation collections. This feature is useful when
    applications that need the low pause times provided by the concurrent collector are run on machines
    with small numbers of processors (e.g., 1 or 2). For more information on usage of this mode, see the
    “Tuning Garbage Collection with the 5.0 Java™ Virtual Machine” paper referred to in Section 9.
    When to Use the CMS Collector
    Use the CMS collector if your application needs shorter garbage collection pauses and can afford to
    share processor resources with the garbage collector when the application is running. (Due to its
    concurrency, the CMS collector takes CPU cycles away from the application during a collection cycle.)
    Typically, applications that have a relatively large set of long-lived data (a large old generation), and that
    run on machines with two or more processors, tend to benefit from the use of this collector. An example
    would be web servers. The CMS collector should be considered for any application with a low pause time
    requirement. It may also give good results for interactive applications with old generations of a modest
    size on a single processor.
    CMS Collector Selection
    If you want the CMS collector to be used, you must explicitly select it by specifying the command line
    option -XX:+UseConcMarkSweepGC. If you want it to be run in incremental mode, also enable that
    mode via the –XX:+CMSIncrementalMode option.

  • 相关阅读:
    每天一道LeetCode--141.Linked List Cycle(链表环问题)
    每天一道LeetCode--119.Pascal's Triangle II(杨辉三角)
    每天一道LeetCode--118. Pascal's Triangle(杨辉三角)
    CF1277D Let's Play the Words?
    CF1281B Azamon Web Services
    CF1197D Yet Another Subarray Problem
    CF1237D Balanced Playlist
    CF1239A Ivan the Fool and the Probability Theory
    CF1223D Sequence Sorting
    CF1228D Complete Tripartite
  • 原文地址:https://www.cnblogs.com/zno2/p/4600153.html
Copyright © 2020-2023  润新知