changeset 8488:c60b0994e8ee jdk8u121-b34

8170888: [linux] Experimental support for cgroup memory limits in container (ie Docker) environments Summary: Set apparent physical memory to cgroup memory limit when UseCGroupMemoryLimitForHeap is true Reviewed-by: acorn, gtriantafill Contributed-by: Christine Flood <chf@redhat.com>
author dholmes
date Thu, 05 Jan 2017 18:55:20 -0500
parents fa112b882e3c
children 0b3b35f008f2
files src/share/vm/runtime/arguments.cpp src/share/vm/runtime/globals.hpp
diffstat 2 files changed, 36 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/runtime/arguments.cpp	Tue Dec 20 16:06:10 2016 -0500
+++ b/src/share/vm/runtime/arguments.cpp	Thu Jan 05 18:55:20 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1768,10 +1768,39 @@
     FLAG_SET_CMDLINE(uintx, MaxRAMFraction, DefaultMaxRAMFraction);
   }
 
-  const julong phys_mem =
+  julong phys_mem =
     FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM)
                             : (julong)MaxRAM;
 
+  // Experimental support for CGroup memory limits
+  if (UseCGroupMemoryLimitForHeap) {
+    // This is a rough indicator that a CGroup limit may be in force
+    // for this process
+    const char* lim_file = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
+    FILE *fp = fopen(lim_file, "r");
+    if (fp != NULL) {
+      julong cgroup_max = 0;
+      int ret = fscanf(fp, JULONG_FORMAT, &cgroup_max);
+      if (ret == 1 && cgroup_max > 0) {
+        // If unlimited, cgroup_max will be a very large, but unspecified
+        // value, so use initial phys_mem as a limit
+        if (PrintGCDetails && Verbose) {
+          // Cannot use gclog_or_tty yet.
+          tty->print_cr("Setting phys_mem to the min of cgroup limit ("
+                        JULONG_FORMAT "MB) and initial phys_mem ("
+                        JULONG_FORMAT "MB)", cgroup_max/M, phys_mem/M);
+        }
+        phys_mem = MIN2(cgroup_max, phys_mem);
+      } else {
+        warning("Unable to read/parse cgroup memory limit from %s: %s",
+                lim_file, errno != 0 ? strerror(errno) : "unknown error");
+      }
+      fclose(fp);
+    } else {
+      warning("Unable to open cgroup memory limit file %s (%s)", lim_file, strerror(errno));
+    }
+  }
+
   // If the maximum heap size has not been set with -Xmx,
   // then set it as fraction of the size of physical memory,
   // respecting the maximum and minimum sizes of the heap.
--- a/src/share/vm/runtime/globals.hpp	Tue Dec 20 16:06:10 2016 -0500
+++ b/src/share/vm/runtime/globals.hpp	Thu Jan 05 18:55:20 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2068,6 +2068,10 @@
           "Maximum ergonomically set heap size (in bytes); zero means use " \
           "MaxRAM / MaxRAMFraction")                                        \
                                                                             \
+  experimental(bool, UseCGroupMemoryLimitForHeap, false,                    \
+          "Use CGroup memory limit as physical memory limit for heap "      \
+          "sizing")                                                         \
+                                                                            \
   product(uintx, MaxRAMFraction, 4,                                         \
           "Maximum fraction (1/n) of real memory used for maximum heap "    \
           "size")                                                           \