JDK-8061259 : ParNew promotion failed is serialized on a lock
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • Submitted: 2014-10-16
  • Updated: 2015-09-29
  • Resolved: 2015-01-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u60Fixed 9 b49Fixed
Description
The following short program, run with:

-Xmx2g -Xms2g -Xmn1g -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -XX:ParallelGCThreads=6 PromoFail 4

causes ParNew to report promotion failed after an excessive amount of time.

-----

import java.util.LinkedList;
class PromoFail {

  static class Container {

    Container p;
    byte[] a;

    public Container(int size) {
      if (size > 0) {
        p = new Container(size / 2);
      } else {
        p = null;
      }
      a = new byte[size];
    }
  }

  public static void main(String args[]) {
    if (args.length < 1) {
      System.err.println("@ 1st argument must be size in MB.");
      System.exit(1);
    }
    int size = 0;
    try {
      size = Integer.parseInt(args[0]) * 1024 * 1024;
    } catch (NumberFormatException e) {
      System.err.println("@ Cannot parse the size(=" + args[0] + ")");
      System.exit(1);
    }

    // LinkedList will have more unbalanced workload.
    LinkedList<Container> list = new LinkedList<Container>();

    // 1st iteration adds element without removal.
    // These are all live objects.
    for (int i = 0; i < size / 4; i++) {
      list.add(new Container(1));
    }
    // Promote to the old gen.
    System.gc();

    for (int container_size = 2; container_size < 512; container_size *= 3) {
      for (int i = 0; i < size / 4; i++) {
        // Most likely removing an old object due to System.gc() from previous iteration.
        // This will cause fragmentation.
        list.remove();
        list.add(new Container(container_size));
      }

      {
        System.gc();
        Runtime runtime = Runtime.getRuntime();
        System.out.println("@ Current Used: "
            + (runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024);
      }
    }
  }
}

Comments
Changing from enhancement to bug since this is more of a performance bug than a new feature.
15-04-2015

From mail from Jungwoo ========================= You can run it with the following parameters. $ java -Xmx2g -Xms2g -Xmn1g -XX:+UseCMSFastPromotionFailure -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -XX:ParallelGCThreads=6 PromoFail 4 Without UseCMSFastPromotionFailure #7: [GC (Allocation Failure) #7: [ParNew#6: [CMS-concurrent-abortable-preclean: 0.003/0.203 secs] [Times: user=0.20 sys=0.20 real=0.20 secs] (promotion failed): 838912K->943744K(943744K), 62.0419534 secs]#8: [CMS (concurrent mode failure): 1048441K->1048575K(1048576K), 1.7731336 secs] 1609551K->1170596K(1992320K), [Metaspace: 3547K->3547K(1056768K)], 63.8151607secs] [Times: user=93.50 sys=22.12 real=63.82 secs] With UseCMSFastPromotionFailure #7: [GC (Allocation Failure) #7: [ParNew#6: [CMS-concurrent-abortable-preclean: 0.004/0.204 secs] [Times: user=0.30 sys=0.02 real=0.20 secs] (promotion failed): 838912K->943744K(943744K), 2.0949545 secs]#8: [CMS (concurrent mode failure): 1048363K->1048575K(1048576K), 1.7517250 secs] 1609551K->1170595K(1992320K), [Metaspace: 3546K->3546K(1056768K)], 3.8467384secs] [Times: user=10.85 sys=1.04 real=3.85 secs] ========================= We've seen similar numbers for the testcase in the description.
27-10-2014

jwha@google.com will provide a webrev with a suggested fix.
16-10-2014