Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8296344

Remove dependency on G1 for writing the CDS archive heap

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Fixed
    • Icon: P4 P4
    • 21
    • 20
    • hotspot
    • b10

      Currently the dumping of the CDS archive heap has complex interaction with G1. Each time a Java object needs to be archived, we allocate a copy of this object using G1CollectedHeap::archive_mem_allocate(). The problems are:

      - The complex interface makes it difficult to implement heap archiving for other collectors.

      - When the G1 heap is fragmented, we may not be able to allocate the archived objects in the desired address range, resulting in a suboptimal archive.

      Proposal:

      Since we don't use the archived objects at dump time, they don't need to be stored inside the dumptime heap. Instead of asking G1 to give us real memory from the dump time heap for storing the archived objects, we manage a buffer ourselves when copying the objects.

      The goal is to generate a CDS heap image that has the same format as generated by the previous dumping algorithm. I.e.,

      - The archive heap is divided in 'open' and 'closed' parts.
      - At runtime, the archive heap can be mapped with the existing G1CollectedHeap::alloc_archive_regions() API

      (Note: a follow-up RFE will simplify the runtime mapping code and consolidate all archived objects into a single block. No more 'open' and 'close' parts -- see JDK-8298048).

      =================================================
      Algorithm:

      - Identify the java heap objects that need to be archived => remember these objects in a hashtable. Each object is associated with an 'open' or 'closed' attribute.

      - Allocate a GrowableArray as a temporary buffer. The GrowableArray is divided into multiple 1MB blocks.

      - Start at position 0 of the buffer: copy the all the 'open' objects in the hashtable sequentially into the GrowableArray

      - Advance to the next position P in the buffer, where P is aligned with G1's region size (HeapRegion::GrainBytes)

      - Copy the all the 'closed' objects in the hashtable sequentially into the GrowableArray

      - When the objects are being copied, add appropriate fillers such that no objects cross 1MB boundaries. (**)

      - After all the objects are copied, calculate the requested addresses of the copied objects. We do so by "moving" the GrowableArray such that it will be flushed against the end of the current G1 heap.

      - E.g., if all the copied objects can fit in 2 G1 regions, then the lowest copied object Foo would sit at the lowest address of the second G1 region from the top of the heap. This is called the "requested address" of Foo. By default, we want to map Foo at this address at runtime.

      - Relocate all the oop fields in the copied objects according to their requested addresses.

      - Write the contents of the GrowableArray into the CDS archive, separating the "open" portion from the "closed" portion.
      =================================================

      (**) The size of G1 regions depends on the max heap size, but is never smaller than 1MB. By ensuring that no objects in the archive heap cross 1MB boundaries, we can always map the archive regardless of the runtime G1 region size. (This 1MB value may need to be reconsidered when we support archive heap mapping in other region-based collectors.)

      The benefit is less CDS-specific code in G1. It also makes it possible to dump the archive heap with non-G1 collectors (see follow-up RFE JDK-8298614).

            iklam Ioi Lam
            iklam Ioi Lam
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: