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

G1 is slow at startup due to initial heap commits

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 25
    • 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.

            Unassigned Unassigned
            shade Aleksey Shipilev
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: