8170888: [linux] Experimental support for cgroup memory limits in container (ie Docker) environments
authordholmes
Mon, 12 Dec 2016 15:41:50 -0500
changeset 42654 6bf23e6fb9ca
parent 42653 62a5d76872d4
child 42655 19eda0e558da
child 42657 9e1850986b28
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, kbarrett Contributed-by: Christine Flood <chf@redhat.com>
hotspot/src/share/vm/runtime/arguments.cpp
hotspot/src/share/vm/runtime/globals.hpp
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Mon Dec 12 11:29:51 2016 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Mon Dec 12 15:41:50 2016 -0500
@@ -2038,10 +2038,36 @@
 static const size_t DefaultHeapBaseMinAddress = HeapBaseMinAddress;
 
 void Arguments::set_heap_size() {
-  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
+        log_info(gc, heap)("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/hotspot/src/share/vm/runtime/globals.hpp	Mon Dec 12 11:29:51 2016 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Mon Dec 12 15:41:50 2016 -0500
@@ -2037,6 +2037,10 @@
           "MaxRAM / MaxRAMFraction")                                        \
           range(0, max_uintx)                                               \
                                                                             \
+  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")                                                           \