G1 is slow at startup due to initial heap commits

XMLWordPrintable

    • Type: Enhancement
    • Resolution: Duplicate
    • Priority: P4
    • tbd
    • Affects Version/s: 25
    • Component/s: hotspot
    • gc

      I have been doing some startup time research for Leyden and different GCs, and noticed that G1 startup time varies wildly depending on the heap size requested.

      Look:

      $ cat Hello.java
      public class Hello {
        public static void main(String... args) throws Throwable {
          System.out.println("Hello world!");
        }
      }

      $ javac Hello.java

      $ hyperfine -w 10 -r 10 "build/linux-x86_64-server-release/images/jdk/bin/java -XX:+UseG1GC -Xmx128m Hello"
      Benchmark 1: build/linux-x86_64-server-release/images/jdk/bin/java -XX:+UseG1GC -Xmx128m Hello
        Time (mean ± σ): 22.5 ms ± 0.5 ms [User: 13.6 ms, System: 17.3 ms]
        Range (min ... max): 22.1 ms ... 23.7 ms 10 runs

      $ hyperfine -w 10 -r 10 "build/linux-x86_64-server-release/images/jdk/bin/java -XX:+UseG1GC -Xmx2g Hello"
      Benchmark 1: build/linux-x86_64-server-release/images/jdk/bin/java -XX:+UseG1GC -Xmx2g Hello
        Time (mean ± σ): 43.8 ms ± 2.3 ms [User: 16.4 ms, System: 35.5 ms]
        Range (min ... max): 41.7 ms ... 48.3 ms 10 runs

      Profiling shows the hot path is in heap region commits.

                     - 44.45% Threads::create_vm(JavaVMInitArgs*, bool*)
                        - 32.03% init_globals()
                           - 31.10% universe_init()
                              - 26.44% G1CollectedHeap::initialize()
                                 - 25.84% G1CollectedHeap::expand(unsigned long, WorkerThreads*, double*)
                                    - G1HeapRegionManager::expand_by(unsigned int, WorkerThreads*)
                                       - 20.38% G1HeapRegionManager::expand(unsigned int, unsigned int, WorkerThreads
                                          - 9.70% G1HeapRegionManager::commit_regions(unsigned int, unsigned long, Wo
                                             - 8.07% G1RegionsSmallerThanCommitSizeMapper::commit_regions(unsigned in
                                                - 7.99% G1PageBasedVirtualSpace::commit(unsigned long, unsigned long)
                                                   + 7.92% os::commit_memory_or_exit(char*, unsigned long, unsigned l
                                             + 1.53% G1FromCardCache::invalidate(unsigned int, unsigned long)
                                          - 8.73% G1RegionsSmallerThanCommitSizeMapper::commit_regions(unsigned int,
                                             - G1PageBasedVirtualSpace::commit(unsigned long, unsigned long)
                                                + 8.55% os::commit_memory_or_exit(char*, unsigned long, unsigned long
                                          - 1.83% G1CollectedHeap::new_heap_region(unsigned int, MemRegion)
                                             - G1HeapRegion::G1HeapRegion(unsigned int, G1BlockOffsetTable*, MemRegio
                                                - 1.37% G1HeapRegionRemSet::G1HeapRegionRemSet(G1HeapRegion*, G1CardS
                                                     0.70% G1CardSetMemoryManager::G1CardSetMemoryManager(G1CardSetCo
                                       + 4.81% __memset_avx2_unaligned_erms
                                       + 0.65% G1HeapRegionManager::initialize_regions(unsigned int, unsigned int)
                              + 3.35% Metaspace::global_initialize()
                                0.60% MetaspaceShared::initialize_shared_spaces()

      Reducing -Xms helps:

      $ hyperfine -w 10 -r 10 "build/linux-x86_64-server-release/images/jdk/bin/java -XX:+UseG1GC -Xms128m -Xmx2g Hello"
      Benchmark 1: build/linux-x86_64-server-release/images/jdk/bin/java -XX:+UseG1GC -Xms128m -Xmx2g Hello
        Time (mean ± σ): 23.4 ms ± 0.4 ms [User: 12.6 ms, System: 18.5 ms]
        Range (min … max): 22.9 ms … 24.1 ms 10 runs

      While we should really consider to trim the default initial heap size (JDK-8348278), it would not help if user specifies Xms. So, it would be great to see if we can improve this code path across large initial heap sizes.

            Assignee:
            Unassigned
            Reporter:
            Aleksey Shipilev
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: