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

EpsilonMaxTLABSize automatic adjustment allows too small TLABs


    • Type: Bug
    • Status: Open
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: 14
    • Fix Version/s: 16
    • Component/s: hotspot
    • Labels:
    • Subcomponent:


      Use of small values of EpsilonMaxTLABSize results in too small actual TLAB sizes.

      E.g. logging in ThreadLocalAllocBuffer::initial_desired_size() around determining the TLAB size:

        log_error(gc, tlab)("TLAB min: " SIZE_FORMAT " initial: " SIZE_FORMAT " max: " SIZE_FORMAT,
                                     min_size(), init_sz, max_size());

        init_sz = MIN2(MAX2(init_sz, min_size()), max_size());
        log_error(gc, tlab)("result size " SIZE_FORMAT, init_sz);

      and running a HelloWorld with

      ~/Downloads/vmshare/jdk10/hs/build/linux-x64-debug/images/jdk/bin/java -XX:+UnlockExperimentalVMOptions -XX:EpsilonMaxTLABSize=1 -XX:+UseEpsilonGC HelloWorld

      results in this output:

      [0.008s][error ][gc,tlab] TLAB min: 328 initial: 5270046 max: 256
      [0.008s][error ][gc,tlab] result size 256

      I.e. the used TLAB is too small, potentially so small (with larger reserve for allocation prefetch) so that it can't contain any object.

      E.g. $java -XX:AllocatePrefetchDistance=512 -XX:AllocatePrefetchLines=64 -XX:MinTLABSize=4736 -XX:+UnlockExperimentalVMOptions -XX:EpsilonMaxTLABSize=1 -XX:+UseEpsilonGC HelloWorld

      [0.007s][error ][gc] allocation-prefetch 592 // the reserve for allocation prefetch
      [0.007s][error ][gc,tlab] TLAB min: 1184 initial: 5270046 max: 592
      [0.007s][error ][gc,tlab] result size 592

      This disables TLABs effectively afaict.

      Other collectors are not affected afaict: their (calculated) maximum TLAB size is always much larger than the reserve.

      The other problem is that with JDK-8233702 the code will assert and fail the VM, because the introduced check in the "init_sz" calculation

        init_sz = clamp(init_sz, min_size(), max_size());

      will notice that ThreadLocalAllocBuffer::max_size() < ThreadLocalAllocBuffer::min_size().

      The reason for this failure is some initialization code in epsilonArguments.cpp:

        if (EpsilonMaxTLABSize < MinTLABSize) {
          log_warning(gc)("EpsilonMaxTLABSize < MinTLABSize, adjusting it to " SIZE_FORMAT, MinTLABSize);
          EpsilonMaxTLABSize = MinTLABSize;

      and initialization of ThreadLocalBuffer::max_size() in epsilonHeap.cpp:

        _max_tlab_size = MIN2(CollectedHeap::max_tlab_size(), align_object_size(EpsilonMaxTLABSize / HeapWordSize));

      (_max_tlab_size is later used to set ThreadLocalAllocBuffer::max_size() directly)




            • Assignee:
              tschatzl Thomas Schatzl
            • Votes:
              0 Vote for this issue
              2 Start watching this issue


              • Created: