Merge

Mon, 09 Jul 2018 15:45:22 +0000

author
kevinw
date
Mon, 09 Jul 2018 15:45:22 +0000
changeset 9350
aeacee5afc4d
parent 9349
e25662a88116
parent 9348
cb9634ab2906
child 9351
bae7d3cdf6af

Merge

     1.1 --- a/.hgtags	Mon Jul 09 05:53:08 2018 -0700
     1.2 +++ b/.hgtags	Mon Jul 09 15:45:22 2018 +0000
     1.3 @@ -1157,3 +1157,4 @@
     1.4  083a9d6562100353708e4b73656282b21a78f714 jdk8u172-b11
     1.5  c19c5b73704e3d188bedfe52a473b408ca39009f jdk8u182-b00
     1.6  0341fa6dbb363ee4dc5dbf5bfc4f820523400a72 jdk8u192-b00
     1.7 +5792d995ed26eec0417d96a2423446bbcd6951a9 jdk8u192-b01
     2.1 --- a/make/linux/makefiles/jsig.make	Mon Jul 09 05:53:08 2018 -0700
     2.2 +++ b/make/linux/makefiles/jsig.make	Mon Jul 09 15:45:22 2018 +0000
     2.3 @@ -57,14 +57,15 @@
     2.4                           $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(EXTRA_CFLAGS) -o $@ $< -ldl
     2.5  ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
     2.6  	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO)
     2.7 +  ifeq ($(STRIP_POLICY),all_strip)
     2.8  	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@
     2.9 -  ifeq ($(STRIP_POLICY),all_strip)
    2.10  	$(QUIETLY) $(STRIP) $@
    2.11    else
    2.12      ifeq ($(STRIP_POLICY),min_strip)
    2.13 +	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@
    2.14  	$(QUIETLY) $(STRIP) -g $@
    2.15 +    endif
    2.16      # implied else here is no stripping at all
    2.17 -    endif
    2.18    endif
    2.19    ifeq ($(ZIP_DEBUGINFO_FILES),1)
    2.20  	$(ZIPEXE) -q -y $(LIBJSIG_DIZ) $(LIBJSIG_DEBUGINFO)
     3.1 --- a/make/linux/makefiles/saproc.make	Mon Jul 09 05:53:08 2018 -0700
     3.2 +++ b/make/linux/makefiles/saproc.make	Mon Jul 09 15:45:22 2018 +0000
     3.3 @@ -100,14 +100,15 @@
     3.4  	           -lthread_db
     3.5  ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
     3.6  	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBSAPROC_DEBUGINFO)
     3.7 +  ifeq ($(STRIP_POLICY),all_strip)
     3.8  	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@
     3.9 -  ifeq ($(STRIP_POLICY),all_strip)
    3.10  	$(QUIETLY) $(STRIP) $@
    3.11    else
    3.12      ifeq ($(STRIP_POLICY),min_strip)
    3.13 +	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@
    3.14  	$(QUIETLY) $(STRIP) -g $@
    3.15 +    endif
    3.16      # implied else here is no stripping at all
    3.17 -    endif
    3.18    endif
    3.19    ifeq ($(ZIP_DEBUGINFO_FILES),1)
    3.20  	$(ZIPEXE) -q -y $(LIBSAPROC_DIZ) $(LIBSAPROC_DEBUGINFO)
     4.1 --- a/make/linux/makefiles/vm.make	Mon Jul 09 05:53:08 2018 -0700
     4.2 +++ b/make/linux/makefiles/vm.make	Mon Jul 09 15:45:22 2018 +0000
     4.3 @@ -358,14 +358,15 @@
     4.4  
     4.5  ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
     4.6  	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DEBUGINFO)
     4.7 +  ifeq ($(STRIP_POLICY),all_strip)
     4.8  	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@
     4.9 -  ifeq ($(STRIP_POLICY),all_strip)
    4.10  	$(QUIETLY) $(STRIP) $@
    4.11    else
    4.12      ifeq ($(STRIP_POLICY),min_strip)
    4.13 +	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@
    4.14  	$(QUIETLY) $(STRIP) -g $@
    4.15 +    endif
    4.16      # implied else here is no stripping at all
    4.17 -    endif
    4.18    endif
    4.19    ifeq ($(ZIP_DEBUGINFO_FILES),1)
    4.20  	$(ZIPEXE) -q -y $(LIBJVM_DIZ) $(LIBJVM_DEBUGINFO)
     5.1 --- a/src/os/aix/vm/os_aix.cpp	Mon Jul 09 05:53:08 2018 -0700
     5.2 +++ b/src/os/aix/vm/os_aix.cpp	Mon Jul 09 15:45:22 2018 +0000
     5.3 @@ -4008,6 +4008,16 @@
     5.4  };
     5.5  
     5.6  int os::active_processor_count() {
     5.7 +  // User has overridden the number of active processors
     5.8 +  if (ActiveProcessorCount > 0) {
     5.9 +    if (PrintActiveCpus) {
    5.10 +      tty->print_cr("active_processor_count: "
    5.11 +                    "active processor count set by user : %d",
    5.12 +                     ActiveProcessorCount);
    5.13 +    }
    5.14 +    return ActiveProcessorCount;
    5.15 +  }
    5.16 +
    5.17    int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
    5.18    assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
    5.19    return online_cpus;
     6.1 --- a/src/os/bsd/vm/os_bsd.cpp	Mon Jul 09 05:53:08 2018 -0700
     6.2 +++ b/src/os/bsd/vm/os_bsd.cpp	Mon Jul 09 15:45:22 2018 +0000
     6.3 @@ -3765,6 +3765,16 @@
     6.4  };
     6.5  
     6.6  int os::active_processor_count() {
     6.7 +  // User has overridden the number of active processors
     6.8 +  if (ActiveProcessorCount > 0) {
     6.9 +    if (PrintActiveCpus) {
    6.10 +      tty->print_cr("active_processor_count: "
    6.11 +                    "active processor count set by user : %d",
    6.12 +                     ActiveProcessorCount);
    6.13 +    }
    6.14 +    return ActiveProcessorCount;
    6.15 +  }
    6.16 +
    6.17    return _processor_count;
    6.18  }
    6.19  
     7.1 --- a/src/os/linux/vm/globals_linux.hpp	Mon Jul 09 05:53:08 2018 -0700
     7.2 +++ b/src/os/linux/vm/globals_linux.hpp	Mon Jul 09 15:45:22 2018 +0000
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
     7.6 + * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
     7.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.8   *
     7.9   * This code is free software; you can redistribute it and/or modify it
    7.10 @@ -49,8 +49,13 @@
    7.11    product(bool, UseSHM, false,                                          \
    7.12            "Use SYSV shared memory for large pages")                     \
    7.13                                                                          \
    7.14 -  diagnostic(bool, PrintActiveCpus, false,                              \
    7.15 -          "Print the number of CPUs detected in os::active_processor_count")
    7.16 +  product(bool, UseContainerSupport, true,                              \
    7.17 +          "Enable detection and runtime container configuration support") \
    7.18 +                                                                        \
    7.19 +  product(bool, PreferContainerQuotaForCPUCount, true,                  \
    7.20 +          "Calculate the container CPU availability based on the value" \
    7.21 +          " of quotas (if set), when true. Otherwise, use the CPU"      \
    7.22 +          " shares value, provided it is less than quota.")
    7.23  
    7.24  //
    7.25  // Defines Linux-specific default values. The flags are available on all
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/os/linux/vm/osContainer_linux.cpp	Mon Jul 09 15:45:22 2018 +0000
     8.3 @@ -0,0 +1,680 @@
     8.4 +/*
     8.5 + * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.
    8.11 + *
    8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.15 + * version 2 for more details (a copy is included in the LICENSE file that
    8.16 + * accompanied this code).
    8.17 + *
    8.18 + * You should have received a copy of the GNU General Public License version
    8.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.21 + *
    8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.23 + * or visit www.oracle.com if you need additional information or have any
    8.24 + * questions.
    8.25 + *
    8.26 + */
    8.27 +
    8.28 +#include <string.h>
    8.29 +#include <math.h>
    8.30 +#include <errno.h>
    8.31 +#include "utilities/globalDefinitions.hpp"
    8.32 +#include "memory/allocation.hpp"
    8.33 +#include "runtime/os.hpp"
    8.34 +#include "osContainer_linux.hpp"
    8.35 +
    8.36 +#define PER_CPU_SHARES 1024
    8.37 +
    8.38 +bool  OSContainer::_is_initialized   = false;
    8.39 +bool  OSContainer::_is_containerized = false;
    8.40 +julong _unlimited_memory;
    8.41 +
    8.42 +class CgroupSubsystem: CHeapObj<mtInternal> {
    8.43 + friend class OSContainer;
    8.44 +
    8.45 + private:
    8.46 +    /* mountinfo contents */
    8.47 +    char *_root;
    8.48 +    char *_mount_point;
    8.49 +
    8.50 +    /* Constructed subsystem directory */
    8.51 +    char *_path;
    8.52 +
    8.53 + public:
    8.54 +    CgroupSubsystem(char *root, char *mountpoint) {
    8.55 +      _root = os::strdup(root);
    8.56 +      _mount_point = os::strdup(mountpoint);
    8.57 +      _path = NULL;
    8.58 +    }
    8.59 +
    8.60 +    /*
    8.61 +     * Set directory to subsystem specific files based
    8.62 +     * on the contents of the mountinfo and cgroup files.
    8.63 +     */
    8.64 +    void set_subsystem_path(char *cgroup_path) {
    8.65 +      char buf[MAXPATHLEN+1];
    8.66 +      if (_root != NULL && cgroup_path != NULL) {
    8.67 +        if (strcmp(_root, "/") == 0) {
    8.68 +          int buflen;
    8.69 +          strncpy(buf, _mount_point, MAXPATHLEN);
    8.70 +          buf[MAXPATHLEN-1] = '\0';
    8.71 +          if (strcmp(cgroup_path,"/") != 0) {
    8.72 +            buflen = strlen(buf);
    8.73 +            if ((buflen + strlen(cgroup_path)) > (MAXPATHLEN-1)) {
    8.74 +              return;
    8.75 +            }
    8.76 +            strncat(buf, cgroup_path, MAXPATHLEN-buflen);
    8.77 +            buf[MAXPATHLEN-1] = '\0';
    8.78 +          }
    8.79 +          _path = os::strdup(buf);
    8.80 +        } else {
    8.81 +          if (strcmp(_root, cgroup_path) == 0) {
    8.82 +            strncpy(buf, _mount_point, MAXPATHLEN);
    8.83 +            buf[MAXPATHLEN-1] = '\0';
    8.84 +            _path = os::strdup(buf);
    8.85 +          } else {
    8.86 +            char *p = strstr(_root, cgroup_path);
    8.87 +            if (p != NULL && p == _root) {
    8.88 +              if (strlen(cgroup_path) > strlen(_root)) {
    8.89 +                int buflen;
    8.90 +                strncpy(buf, _mount_point, MAXPATHLEN);
    8.91 +                buf[MAXPATHLEN-1] = '\0';
    8.92 +                buflen = strlen(buf);
    8.93 +                if ((buflen + strlen(cgroup_path)) > (MAXPATHLEN-1)) {
    8.94 +                  return;
    8.95 +                }
    8.96 +                strncat(buf, cgroup_path + strlen(_root), MAXPATHLEN-buflen);
    8.97 +                buf[MAXPATHLEN-1] = '\0';
    8.98 +                _path = os::strdup(buf);
    8.99 +              }
   8.100 +            }
   8.101 +          }
   8.102 +        }
   8.103 +      }
   8.104 +    }
   8.105 +
   8.106 +    char *subsystem_path() { return _path; }
   8.107 +};
   8.108 +
   8.109 +CgroupSubsystem* memory = NULL;
   8.110 +CgroupSubsystem* cpuset = NULL;
   8.111 +CgroupSubsystem* cpu = NULL;
   8.112 +CgroupSubsystem* cpuacct = NULL;
   8.113 +
   8.114 +typedef char * cptr;
   8.115 +
   8.116 +PRAGMA_DIAG_PUSH
   8.117 +PRAGMA_FORMAT_NONLITERAL_IGNORED
   8.118 +template <typename T> int subsystem_file_contents(CgroupSubsystem* c,
   8.119 +                                              const char *filename,
   8.120 +                                              const char *scan_fmt,
   8.121 +                                              T returnval) {
   8.122 +  FILE *fp = NULL;
   8.123 +  char *p;
   8.124 +  char file[MAXPATHLEN+1];
   8.125 +  char buf[MAXPATHLEN+1];
   8.126 +
   8.127 +  if (c == NULL) {
   8.128 +    if (PrintContainerInfo) {
   8.129 +      tty->print_cr("subsystem_file_contents: CgroupSubsytem* is NULL");
   8.130 +    }
   8.131 +    return OSCONTAINER_ERROR;
   8.132 +  }
   8.133 +  if (c->subsystem_path() == NULL) {
   8.134 +    if (PrintContainerInfo) {
   8.135 +      tty->print_cr("subsystem_file_contents: subsystem path is NULL");
   8.136 +    }
   8.137 +    return OSCONTAINER_ERROR;
   8.138 +  }
   8.139 +
   8.140 +  strncpy(file, c->subsystem_path(), MAXPATHLEN);
   8.141 +  file[MAXPATHLEN-1] = '\0';
   8.142 +  int filelen = strlen(file);
   8.143 +  if ((filelen + strlen(filename)) > (MAXPATHLEN-1)) {
   8.144 +    if (PrintContainerInfo) {
   8.145 +      tty->print_cr("File path too long %s, %s", file, filename);
   8.146 +    }
   8.147 +    return OSCONTAINER_ERROR;
   8.148 +  }
   8.149 +  strncat(file, filename, MAXPATHLEN-filelen);
   8.150 +  if (PrintContainerInfo) {
   8.151 +    tty->print_cr("Path to %s is %s", filename, file);
   8.152 +  }
   8.153 +  fp = fopen(file, "r");
   8.154 +  if (fp != NULL) {
   8.155 +    p = fgets(buf, MAXPATHLEN, fp);
   8.156 +    if (p != NULL) {
   8.157 +      int matched = sscanf(p, scan_fmt, returnval);
   8.158 +      if (matched == 1) {
   8.159 +        fclose(fp);
   8.160 +        return 0;
   8.161 +      } else {
   8.162 +        if (PrintContainerInfo) {
   8.163 +          tty->print_cr("Type %s not found in file %s", scan_fmt, file);
   8.164 +        }
   8.165 +      }
   8.166 +    } else {
   8.167 +      if (PrintContainerInfo) {
   8.168 +        tty->print_cr("Empty file %s", file);
   8.169 +      }
   8.170 +    }
   8.171 +  } else {
   8.172 +    if (PrintContainerInfo) {
   8.173 +      tty->print_cr("Open of file %s failed, %s", file, strerror(errno));
   8.174 +    }
   8.175 +  }
   8.176 +  if (fp != NULL)
   8.177 +    fclose(fp);
   8.178 +  return OSCONTAINER_ERROR;
   8.179 +}
   8.180 +PRAGMA_DIAG_POP
   8.181 +
   8.182 +#define GET_CONTAINER_INFO(return_type, subsystem, filename,              \
   8.183 +                           logstring, scan_fmt, variable)                 \
   8.184 +  return_type variable;                                                   \
   8.185 +{                                                                         \
   8.186 +  int err;                                                                \
   8.187 +  err = subsystem_file_contents(subsystem,                                \
   8.188 +                                filename,                                 \
   8.189 +                                scan_fmt,                                 \
   8.190 +                                &variable);                               \
   8.191 +  if (err != 0)                                                           \
   8.192 +    return (return_type) OSCONTAINER_ERROR;                               \
   8.193 +                                                                          \
   8.194 +  if (PrintContainerInfo)                                                 \
   8.195 +    tty->print_cr(logstring, variable);                                   \
   8.196 +}
   8.197 +
   8.198 +#define GET_CONTAINER_INFO_CPTR(return_type, subsystem, filename,         \
   8.199 +                               logstring, scan_fmt, variable, bufsize)    \
   8.200 +  char variable[bufsize];                                                 \
   8.201 +{                                                                         \
   8.202 +  int err;                                                                \
   8.203 +  err = subsystem_file_contents(subsystem,                                \
   8.204 +                                filename,                                 \
   8.205 +                                scan_fmt,                                 \
   8.206 +                                variable);                                \
   8.207 +  if (err != 0)                                                           \
   8.208 +    return (return_type) NULL;                                            \
   8.209 +                                                                          \
   8.210 +  if (PrintContainerInfo)                                                 \
   8.211 +    tty->print_cr(logstring, variable);                                   \
   8.212 +}
   8.213 +
   8.214 +/* init
   8.215 + *
   8.216 + * Initialize the container support and determine if
   8.217 + * we are running under cgroup control.
   8.218 + */
   8.219 +void OSContainer::init() {
   8.220 +  int mountid;
   8.221 +  int parentid;
   8.222 +  int major;
   8.223 +  int minor;
   8.224 +  FILE *mntinfo = NULL;
   8.225 +  FILE *cgroup = NULL;
   8.226 +  char buf[MAXPATHLEN+1];
   8.227 +  char tmproot[MAXPATHLEN+1];
   8.228 +  char tmpmount[MAXPATHLEN+1];
   8.229 +  char tmpbase[MAXPATHLEN+1];
   8.230 +  char *p;
   8.231 +  jlong mem_limit;
   8.232 +
   8.233 +  assert(!_is_initialized, "Initializing OSContainer more than once");
   8.234 +
   8.235 +  _is_initialized = true;
   8.236 +  _is_containerized = false;
   8.237 +
   8.238 +  _unlimited_memory = (LONG_MAX / os::vm_page_size()) * os::vm_page_size();
   8.239 +
   8.240 +  if (PrintContainerInfo) {
   8.241 +    tty->print_cr("OSContainer::init: Initializing Container Support");
   8.242 +  }
   8.243 +  if (!UseContainerSupport) {
   8.244 +    if (PrintContainerInfo) {
   8.245 +      tty->print_cr("Container Support not enabled");
   8.246 +    }
   8.247 +    return;
   8.248 +  }
   8.249 +
   8.250 +  /*
   8.251 +   * Find the cgroup mount point for memory and cpuset
   8.252 +   * by reading /proc/self/mountinfo
   8.253 +   *
   8.254 +   * Example for docker:
   8.255 +   * 219 214 0:29 /docker/7208cebd00fa5f2e342b1094f7bed87fa25661471a4637118e65f1c995be8a34 /sys/fs/cgroup/memory ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,memory
   8.256 +   *
   8.257 +   * Example for host:
   8.258 +   * 34 28 0:29 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,memory
   8.259 +   */
   8.260 +  mntinfo = fopen("/proc/self/mountinfo", "r");
   8.261 +  if (mntinfo == NULL) {
   8.262 +      if (PrintContainerInfo) {
   8.263 +        tty->print_cr("Can't open /proc/self/mountinfo, %s",
   8.264 +                       strerror(errno));
   8.265 +      }
   8.266 +      return;
   8.267 +  }
   8.268 +
   8.269 +  while ( (p = fgets(buf, MAXPATHLEN, mntinfo)) != NULL) {
   8.270 +    // Look for the filesystem type and see if it's cgroup
   8.271 +    char fstype[MAXPATHLEN+1];
   8.272 +    fstype[0] = '\0';
   8.273 +    char *s =  strstr(p, " - ");
   8.274 +    if (s != NULL &&
   8.275 +        sscanf(s, " - %s", fstype) == 1 &&
   8.276 +        strcmp(fstype, "cgroup") == 0) {
   8.277 +
   8.278 +      if (strstr(p, "memory") != NULL) {
   8.279 +        int matched = sscanf(p, "%d %d %d:%d %s %s",
   8.280 +                             &mountid,
   8.281 +                             &parentid,
   8.282 +                             &major,
   8.283 +                             &minor,
   8.284 +                             tmproot,
   8.285 +                             tmpmount);
   8.286 +        if (matched == 6) {
   8.287 +          memory = new CgroupSubsystem(tmproot, tmpmount);
   8.288 +        }
   8.289 +        else
   8.290 +          if (PrintContainerInfo) {
   8.291 +            tty->print_cr("Incompatible str containing cgroup and memory: %s", p);
   8.292 +          }
   8.293 +      } else if (strstr(p, "cpuset") != NULL) {
   8.294 +        int matched = sscanf(p, "%d %d %d:%d %s %s",
   8.295 +                             &mountid,
   8.296 +                             &parentid,
   8.297 +                             &major,
   8.298 +                             &minor,
   8.299 +                             tmproot,
   8.300 +                             tmpmount);
   8.301 +        if (matched == 6) {
   8.302 +          cpuset = new CgroupSubsystem(tmproot, tmpmount);
   8.303 +        }
   8.304 +        else {
   8.305 +          if (PrintContainerInfo) {
   8.306 +            tty->print_cr("Incompatible str containing cgroup and cpuset: %s", p);
   8.307 +          }
   8.308 +        }
   8.309 +      } else if (strstr(p, "cpu,cpuacct") != NULL || strstr(p, "cpuacct,cpu") != NULL) {
   8.310 +        int matched = sscanf(p, "%d %d %d:%d %s %s",
   8.311 +                             &mountid,
   8.312 +                             &parentid,
   8.313 +                             &major,
   8.314 +                             &minor,
   8.315 +                             tmproot,
   8.316 +                             tmpmount);
   8.317 +        if (matched == 6) {
   8.318 +          cpu = new CgroupSubsystem(tmproot, tmpmount);
   8.319 +          cpuacct = new CgroupSubsystem(tmproot, tmpmount);
   8.320 +        }
   8.321 +        else {
   8.322 +          if (PrintContainerInfo) {
   8.323 +            tty->print_cr("Incompatible str containing cgroup and cpu,cpuacct: %s", p);
   8.324 +          }
   8.325 +        }
   8.326 +      } else if (strstr(p, "cpuacct") != NULL) {
   8.327 +        int matched = sscanf(p, "%d %d %d:%d %s %s",
   8.328 +                             &mountid,
   8.329 +                             &parentid,
   8.330 +                             &major,
   8.331 +                             &minor,
   8.332 +                             tmproot,
   8.333 +                             tmpmount);
   8.334 +        if (matched == 6) {
   8.335 +          cpuacct = new CgroupSubsystem(tmproot, tmpmount);
   8.336 +        }
   8.337 +        else {
   8.338 +          if (PrintContainerInfo) {
   8.339 +            tty->print_cr("Incompatible str containing cgroup and cpuacct: %s", p);
   8.340 +          }
   8.341 +        }
   8.342 +      } else if (strstr(p, "cpu") != NULL) {
   8.343 +        int matched = sscanf(p, "%d %d %d:%d %s %s",
   8.344 +                             &mountid,
   8.345 +                             &parentid,
   8.346 +                             &major,
   8.347 +                             &minor,
   8.348 +                             tmproot,
   8.349 +                             tmpmount);
   8.350 +        if (matched == 6) {
   8.351 +          cpu = new CgroupSubsystem(tmproot, tmpmount);
   8.352 +        }
   8.353 +        else {
   8.354 +          if (PrintContainerInfo) {
   8.355 +            tty->print_cr("Incompatible str containing cgroup and cpu: %s", p);
   8.356 +          }
   8.357 +        }
   8.358 +      }
   8.359 +    }
   8.360 +  }
   8.361 +
   8.362 +  fclose(mntinfo);
   8.363 +
   8.364 +  if (memory == NULL) {
   8.365 +    if (PrintContainerInfo) {
   8.366 +      tty->print_cr("Required cgroup memory subsystem not found");
   8.367 +    }
   8.368 +    return;
   8.369 +  }
   8.370 +  if (cpuset == NULL) {
   8.371 +    if (PrintContainerInfo) {
   8.372 +      tty->print_cr("Required cgroup cpuset subsystem not found");
   8.373 +    }
   8.374 +    return;
   8.375 +  }
   8.376 +  if (cpu == NULL) {
   8.377 +    if (PrintContainerInfo) {
   8.378 +      tty->print_cr("Required cgroup cpu subsystem not found");
   8.379 +    }
   8.380 +    return;
   8.381 +  }
   8.382 +  if (cpuacct == NULL) {
   8.383 +    if (PrintContainerInfo) {
   8.384 +      tty->print_cr("Required cgroup cpuacct subsystem not found");
   8.385 +    }
   8.386 +    return;
   8.387 +  }
   8.388 +
   8.389 +  /*
   8.390 +   * Read /proc/self/cgroup and map host mount point to
   8.391 +   * local one via /proc/self/mountinfo content above
   8.392 +   *
   8.393 +   * Docker example:
   8.394 +   * 5:memory:/docker/6558aed8fc662b194323ceab5b964f69cf36b3e8af877a14b80256e93aecb044
   8.395 +   *
   8.396 +   * Host example:
   8.397 +   * 5:memory:/user.slice
   8.398 +   *
   8.399 +   * Construct a path to the process specific memory and cpuset
   8.400 +   * cgroup directory.
   8.401 +   *
   8.402 +   * For a container running under Docker from memory example above
   8.403 +   * the paths would be:
   8.404 +   *
   8.405 +   * /sys/fs/cgroup/memory
   8.406 +   *
   8.407 +   * For a Host from memory example above the path would be:
   8.408 +   *
   8.409 +   * /sys/fs/cgroup/memory/user.slice
   8.410 +   *
   8.411 +   */
   8.412 +  cgroup = fopen("/proc/self/cgroup", "r");
   8.413 +  if (cgroup == NULL) {
   8.414 +    if (PrintContainerInfo) {
   8.415 +      tty->print_cr("Can't open /proc/self/cgroup, %s",
   8.416 +                     strerror(errno));
   8.417 +      }
   8.418 +    return;
   8.419 +  }
   8.420 +
   8.421 +  while ( (p = fgets(buf, MAXPATHLEN, cgroup)) != NULL) {
   8.422 +    int cgno;
   8.423 +    int matched;
   8.424 +    char *controller;
   8.425 +    char *base;
   8.426 +
   8.427 +    /* Skip cgroup number */
   8.428 +    strsep(&p, ":");
   8.429 +    /* Get controller and base */
   8.430 +    controller = strsep(&p, ":");
   8.431 +    base = strsep(&p, "\n");
   8.432 +
   8.433 +    if (controller != NULL) {
   8.434 +      if (strstr(controller, "memory") != NULL) {
   8.435 +        memory->set_subsystem_path(base);
   8.436 +      } else if (strstr(controller, "cpuset") != NULL) {
   8.437 +        cpuset->set_subsystem_path(base);
   8.438 +      } else if (strstr(controller, "cpu,cpuacct") != NULL || strstr(controller, "cpuacct,cpu") != NULL) {
   8.439 +        cpu->set_subsystem_path(base);
   8.440 +        cpuacct->set_subsystem_path(base);
   8.441 +      } else if (strstr(controller, "cpuacct") != NULL) {
   8.442 +        cpuacct->set_subsystem_path(base);
   8.443 +      } else if (strstr(controller, "cpu") != NULL) {
   8.444 +        cpu->set_subsystem_path(base);
   8.445 +      }
   8.446 +    }
   8.447 +  }
   8.448 +
   8.449 +  fclose(cgroup);
   8.450 +
   8.451 +  // We need to update the amount of physical memory now that
   8.452 +  // command line arguments have been processed.
   8.453 +  if ((mem_limit = memory_limit_in_bytes()) > 0) {
   8.454 +    os::Linux::set_physical_memory(mem_limit);
   8.455 +  }
   8.456 +
   8.457 +  _is_containerized = true;
   8.458 +
   8.459 +}
   8.460 +
   8.461 +const char * OSContainer::container_type() {
   8.462 +  if (is_containerized()) {
   8.463 +    return "cgroupv1";
   8.464 +  } else {
   8.465 +    return NULL;
   8.466 +  }
   8.467 +}
   8.468 +
   8.469 +
   8.470 +/* memory_limit_in_bytes
   8.471 + *
   8.472 + * Return the limit of available memory for this process.
   8.473 + *
   8.474 + * return:
   8.475 + *    memory limit in bytes or
   8.476 + *    -1 for unlimited
   8.477 + *    OSCONTAINER_ERROR for not supported
   8.478 + */
   8.479 +jlong OSContainer::memory_limit_in_bytes() {
   8.480 +  GET_CONTAINER_INFO(julong, memory, "/memory.limit_in_bytes",
   8.481 +                     "Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, memlimit);
   8.482 +
   8.483 +  if (memlimit >= _unlimited_memory) {
   8.484 +    if (PrintContainerInfo) {
   8.485 +      tty->print_cr("Memory Limit is: Unlimited");
   8.486 +    }
   8.487 +    return (jlong)-1;
   8.488 +  }
   8.489 +  else {
   8.490 +    return (jlong)memlimit;
   8.491 +  }
   8.492 +}
   8.493 +
   8.494 +jlong OSContainer::memory_and_swap_limit_in_bytes() {
   8.495 +  GET_CONTAINER_INFO(julong, memory, "/memory.memsw.limit_in_bytes",
   8.496 +                     "Memory and Swap Limit is: " JULONG_FORMAT, JULONG_FORMAT, memswlimit);
   8.497 +  if (memswlimit >= _unlimited_memory) {
   8.498 +    if (PrintContainerInfo) {
   8.499 +      tty->print_cr("Memory and Swap Limit is: Unlimited");
   8.500 +    }
   8.501 +    return (jlong)-1;
   8.502 +  } else {
   8.503 +    return (jlong)memswlimit;
   8.504 +  }
   8.505 +}
   8.506 +
   8.507 +jlong OSContainer::memory_soft_limit_in_bytes() {
   8.508 +  GET_CONTAINER_INFO(julong, memory, "/memory.soft_limit_in_bytes",
   8.509 +                     "Memory Soft Limit is: " JULONG_FORMAT, JULONG_FORMAT, memsoftlimit);
   8.510 +  if (memsoftlimit >= _unlimited_memory) {
   8.511 +    if (PrintContainerInfo) {
   8.512 +      tty->print_cr("Memory Soft Limit is: Unlimited");
   8.513 +    }
   8.514 +    return (jlong)-1;
   8.515 +  } else {
   8.516 +    return (jlong)memsoftlimit;
   8.517 +  }
   8.518 +}
   8.519 +
   8.520 +/* memory_usage_in_bytes
   8.521 + *
   8.522 + * Return the amount of used memory for this process.
   8.523 + *
   8.524 + * return:
   8.525 + *    memory usage in bytes or
   8.526 + *    -1 for unlimited
   8.527 + *    OSCONTAINER_ERROR for not supported
   8.528 + */
   8.529 +jlong OSContainer::memory_usage_in_bytes() {
   8.530 +  GET_CONTAINER_INFO(jlong, memory, "/memory.usage_in_bytes",
   8.531 +                     "Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, memusage);
   8.532 +  return memusage;
   8.533 +}
   8.534 +
   8.535 +/* memory_max_usage_in_bytes
   8.536 + *
   8.537 + * Return the maximum amount of used memory for this process.
   8.538 + *
   8.539 + * return:
   8.540 + *    max memory usage in bytes or
   8.541 + *    OSCONTAINER_ERROR for not supported
   8.542 + */
   8.543 +jlong OSContainer::memory_max_usage_in_bytes() {
   8.544 +  GET_CONTAINER_INFO(jlong, memory, "/memory.max_usage_in_bytes",
   8.545 +                     "Maximum Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, memmaxusage);
   8.546 +  return memmaxusage;
   8.547 +}
   8.548 +
   8.549 +/* active_processor_count
   8.550 + *
   8.551 + * Calculate an appropriate number of active processors for the
   8.552 + * VM to use based on these three inputs.
   8.553 + *
   8.554 + * cpu affinity
   8.555 + * cgroup cpu quota & cpu period
   8.556 + * cgroup cpu shares
   8.557 + *
   8.558 + * Algorithm:
   8.559 + *
   8.560 + * Determine the number of available CPUs from sched_getaffinity
   8.561 + *
   8.562 + * If user specified a quota (quota != -1), calculate the number of
   8.563 + * required CPUs by dividing quota by period.
   8.564 + *
   8.565 + * If shares are in effect (shares != -1), calculate the number
   8.566 + * of CPUs required for the shares by dividing the share value
   8.567 + * by PER_CPU_SHARES.
   8.568 + *
   8.569 + * All results of division are rounded up to the next whole number.
   8.570 + *
   8.571 + * If neither shares or quotas have been specified, return the
   8.572 + * number of active processors in the system.
   8.573 + *
   8.574 + * If both shares and quotas have been specified, the results are
   8.575 + * based on the flag PreferContainerQuotaForCPUCount.  If true,
   8.576 + * return the quota value.  If false return the smallest value
   8.577 + * between shares or quotas.
   8.578 + *
   8.579 + * If shares and/or quotas have been specified, the resulting number
   8.580 + * returned will never exceed the number of active processors.
   8.581 + *
   8.582 + * return:
   8.583 + *    number of CPUs
   8.584 + */
   8.585 +int OSContainer::active_processor_count() {
   8.586 +  int quota_count = 0, share_count = 0;
   8.587 +  int cpu_count, limit_count;
   8.588 +  int result;
   8.589 +
   8.590 +  cpu_count = limit_count = os::Linux::active_processor_count();
   8.591 +  int quota  = cpu_quota();
   8.592 +  int period = cpu_period();
   8.593 +  int share  = cpu_shares();
   8.594 +
   8.595 +  if (quota > -1 && period > 0) {
   8.596 +    quota_count = ceilf((float)quota / (float)period);
   8.597 +    if (PrintContainerInfo) {
   8.598 +      tty->print_cr("CPU Quota count based on quota/period: %d", quota_count);
   8.599 +    }
   8.600 +  }
   8.601 +  if (share > -1) {
   8.602 +    share_count = ceilf((float)share / (float)PER_CPU_SHARES);
   8.603 +    if (PrintContainerInfo) {
   8.604 +      tty->print_cr("CPU Share count based on shares: %d", share_count);
   8.605 +    }
   8.606 +  }
   8.607 +
   8.608 +  // If both shares and quotas are setup results depend
   8.609 +  // on flag PreferContainerQuotaForCPUCount.
   8.610 +  // If true, limit CPU count to quota
   8.611 +  // If false, use minimum of shares and quotas
   8.612 +  if (quota_count !=0 && share_count != 0) {
   8.613 +    if (PreferContainerQuotaForCPUCount) {
   8.614 +      limit_count = quota_count;
   8.615 +    } else {
   8.616 +      limit_count = MIN2(quota_count, share_count);
   8.617 +    }
   8.618 +  } else if (quota_count != 0) {
   8.619 +    limit_count = quota_count;
   8.620 +  } else if (share_count != 0) {
   8.621 +    limit_count = share_count;
   8.622 +  }
   8.623 +
   8.624 +  result = MIN2(cpu_count, limit_count);
   8.625 +  if (PrintContainerInfo) {
   8.626 +    tty->print_cr("OSContainer::active_processor_count: %d", result);
   8.627 +  }
   8.628 +  return result;
   8.629 +}
   8.630 +
   8.631 +char * OSContainer::cpu_cpuset_cpus() {
   8.632 +  GET_CONTAINER_INFO_CPTR(cptr, cpuset, "/cpuset.cpus",
   8.633 +                     "cpuset.cpus is: %s", "%1023s", cpus, 1024);
   8.634 +  return os::strdup(cpus);
   8.635 +}
   8.636 +
   8.637 +char * OSContainer::cpu_cpuset_memory_nodes() {
   8.638 +  GET_CONTAINER_INFO_CPTR(cptr, cpuset, "/cpuset.mems",
   8.639 +                     "cpuset.mems is: %s", "%1023s", mems, 1024);
   8.640 +  return os::strdup(mems);
   8.641 +}
   8.642 +
   8.643 +/* cpu_quota
   8.644 + *
   8.645 + * Return the number of milliseconds per period
   8.646 + * process is guaranteed to run.
   8.647 + *
   8.648 + * return:
   8.649 + *    quota time in milliseconds
   8.650 + *    -1 for no quota
   8.651 + *    OSCONTAINER_ERROR for not supported
   8.652 + */
   8.653 +int OSContainer::cpu_quota() {
   8.654 +  GET_CONTAINER_INFO(int, cpu, "/cpu.cfs_quota_us",
   8.655 +                     "CPU Quota is: %d", "%d", quota);
   8.656 +  return quota;
   8.657 +}
   8.658 +
   8.659 +int OSContainer::cpu_period() {
   8.660 +  GET_CONTAINER_INFO(int, cpu, "/cpu.cfs_period_us",
   8.661 +                     "CPU Period is: %d", "%d", period);
   8.662 +  return period;
   8.663 +}
   8.664 +
   8.665 +/* cpu_shares
   8.666 + *
   8.667 + * Return the amount of cpu shares available to the process
   8.668 + *
   8.669 + * return:
   8.670 + *    Share number (typically a number relative to 1024)
   8.671 + *                 (2048 typically expresses 2 CPUs worth of processing)
   8.672 + *    -1 for no share setup
   8.673 + *    OSCONTAINER_ERROR for not supported
   8.674 + */
   8.675 +int OSContainer::cpu_shares() {
   8.676 +  GET_CONTAINER_INFO(int, cpu, "/cpu.shares",
   8.677 +                     "CPU Shares is: %d", "%d", shares);
   8.678 +  // Convert 1024 to no shares setup
   8.679 +  if (shares == 1024) return -1;
   8.680 +
   8.681 +  return shares;
   8.682 +}
   8.683 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/os/linux/vm/osContainer_linux.hpp	Mon Jul 09 15:45:22 2018 +0000
     9.3 @@ -0,0 +1,68 @@
     9.4 +/*
     9.5 + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.
    9.11 + *
    9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.15 + * version 2 for more details (a copy is included in the LICENSE file that
    9.16 + * accompanied this code).
    9.17 + *
    9.18 + * You should have received a copy of the GNU General Public License version
    9.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.21 + *
    9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.23 + * or visit www.oracle.com if you need additional information or have any
    9.24 + * questions.
    9.25 + *
    9.26 + */
    9.27 +
    9.28 +#ifndef OS_LINUX_VM_OSCONTAINER_LINUX_HPP
    9.29 +#define OS_LINUX_VM_OSCONTAINER_LINUX_HPP
    9.30 +
    9.31 +#include "utilities/globalDefinitions.hpp"
    9.32 +#include "utilities/macros.hpp"
    9.33 +#include "memory/allocation.hpp"
    9.34 +
    9.35 +#define OSCONTAINER_ERROR (-2)
    9.36 +
    9.37 +class OSContainer: AllStatic {
    9.38 +
    9.39 + private:
    9.40 +  static bool   _is_initialized;
    9.41 +  static bool   _is_containerized;
    9.42 +
    9.43 + public:
    9.44 +  static void init();
    9.45 +  static inline bool is_containerized();
    9.46 +  static const char * container_type();
    9.47 +
    9.48 +  static jlong memory_limit_in_bytes();
    9.49 +  static jlong memory_and_swap_limit_in_bytes();
    9.50 +  static jlong memory_soft_limit_in_bytes();
    9.51 +  static jlong memory_usage_in_bytes();
    9.52 +  static jlong memory_max_usage_in_bytes();
    9.53 +
    9.54 +  static int active_processor_count();
    9.55 +
    9.56 +  static char * cpu_cpuset_cpus();
    9.57 +  static char * cpu_cpuset_memory_nodes();
    9.58 +
    9.59 +  static int cpu_quota();
    9.60 +  static int cpu_period();
    9.61 +
    9.62 +  static int cpu_shares();
    9.63 +
    9.64 +};
    9.65 +
    9.66 +inline bool OSContainer::is_containerized() {
    9.67 +  assert(_is_initialized, "OSContainer not initialized");
    9.68 +  return _is_containerized;
    9.69 +}
    9.70 +
    9.71 +#endif // OS_LINUX_VM_OSCONTAINER_LINUX_HPP
    10.1 --- a/src/os/linux/vm/os_linux.cpp	Mon Jul 09 05:53:08 2018 -0700
    10.2 +++ b/src/os/linux/vm/os_linux.cpp	Mon Jul 09 15:45:22 2018 +0000
    10.3 @@ -37,6 +37,7 @@
    10.4  #include "mutex_linux.inline.hpp"
    10.5  #include "oops/oop.inline.hpp"
    10.6  #include "os_share_linux.hpp"
    10.7 +#include "osContainer_linux.hpp"
    10.8  #include "prims/jniFastGetField.hpp"
    10.9  #include "prims/jvm.h"
   10.10  #include "prims/jvm_misc.hpp"
   10.11 @@ -179,13 +180,62 @@
   10.12  julong os::Linux::available_memory() {
   10.13    // values in struct sysinfo are "unsigned long"
   10.14    struct sysinfo si;
   10.15 +  julong avail_mem;
   10.16 +
   10.17 +  if (OSContainer::is_containerized()) {
   10.18 +    jlong mem_limit, mem_usage;
   10.19 +    if ((mem_limit = OSContainer::memory_limit_in_bytes()) < 1) {
   10.20 +      if (PrintContainerInfo) {
   10.21 +        tty->print_cr("container memory limit %s: " JLONG_FORMAT ", using host value",
   10.22 +                       mem_limit == OSCONTAINER_ERROR ? "failed" : "unlimited", mem_limit);
   10.23 +      }
   10.24 +    }
   10.25 +
   10.26 +    if (mem_limit > 0 && (mem_usage = OSContainer::memory_usage_in_bytes()) < 1) {
   10.27 +      if (PrintContainerInfo) {
   10.28 +        tty->print_cr("container memory usage failed: " JLONG_FORMAT ", using host value", mem_usage);
   10.29 +      }
   10.30 +    }
   10.31 +
   10.32 +    if (mem_limit > 0 && mem_usage > 0 ) {
   10.33 +      avail_mem = mem_limit > mem_usage ? (julong)mem_limit - (julong)mem_usage : 0;
   10.34 +      if (PrintContainerInfo) {
   10.35 +        tty->print_cr("available container memory: " JULONG_FORMAT, avail_mem);
   10.36 +      }
   10.37 +      return avail_mem;
   10.38 +    }
   10.39 +  }
   10.40 +
   10.41    sysinfo(&si);
   10.42 -
   10.43 -  return (julong)si.freeram * si.mem_unit;
   10.44 +  avail_mem = (julong)si.freeram * si.mem_unit;
   10.45 +  if (Verbose) {
   10.46 +    tty->print_cr("available memory: " JULONG_FORMAT, avail_mem);
   10.47 +  }
   10.48 +  return avail_mem;
   10.49  }
   10.50  
   10.51  julong os::physical_memory() {
   10.52 -  return Linux::physical_memory();
   10.53 +  jlong phys_mem = 0;
   10.54 +  if (OSContainer::is_containerized()) {
   10.55 +    jlong mem_limit;
   10.56 +    if ((mem_limit = OSContainer::memory_limit_in_bytes()) > 0) {
   10.57 +      if (PrintContainerInfo) {
   10.58 +        tty->print_cr("total container memory: " JLONG_FORMAT, mem_limit);
   10.59 +      }
   10.60 +      return mem_limit;
   10.61 +    }
   10.62 +
   10.63 +    if (PrintContainerInfo) {
   10.64 +      tty->print_cr("container memory limit %s: " JLONG_FORMAT ", using host value",
   10.65 +                     mem_limit == OSCONTAINER_ERROR ? "failed" : "unlimited", mem_limit);
   10.66 +    }
   10.67 +  }
   10.68 +
   10.69 +  phys_mem = Linux::physical_memory();
   10.70 +  if (Verbose) {
   10.71 +    tty->print_cr("total system memory: " JLONG_FORMAT, phys_mem);
   10.72 +  }
   10.73 +  return phys_mem;
   10.74  }
   10.75  
   10.76  ////////////////////////////////////////////////////////////////////////////////
   10.77 @@ -2120,6 +2170,8 @@
   10.78    os::Posix::print_load_average(st);
   10.79  
   10.80    os::Linux::print_full_memory_info(st);
   10.81 +
   10.82 +  os::Linux::print_container_info(st);
   10.83  }
   10.84  
   10.85  // Try to identify popular distros.
   10.86 @@ -2185,6 +2237,57 @@
   10.87     st->cr();
   10.88  }
   10.89  
   10.90 +void os::Linux::print_container_info(outputStream* st) {
   10.91 +if (!OSContainer::is_containerized()) {
   10.92 +    return;
   10.93 +  }
   10.94 +
   10.95 +  st->print("container (cgroup) information:\n");
   10.96 +
   10.97 +  const char *p_ct = OSContainer::container_type();
   10.98 +  st->print("container_type: %s\n", p_ct != NULL ? p_ct : "failed");
   10.99 +
  10.100 +  char *p = OSContainer::cpu_cpuset_cpus();
  10.101 +  st->print("cpu_cpuset_cpus: %s\n", p != NULL ? p : "failed");
  10.102 +  free(p);
  10.103 +
  10.104 +  p = OSContainer::cpu_cpuset_memory_nodes();
  10.105 +  st->print("cpu_memory_nodes: %s\n", p != NULL ? p : "failed");
  10.106 +  free(p);
  10.107 +
  10.108 +  int i = OSContainer::active_processor_count();
  10.109 +  if (i > 0) {
  10.110 +    st->print("active_processor_count: %d\n", i);
  10.111 +  } else {
  10.112 +    st->print("active_processor_count: failed\n");
  10.113 +  }
  10.114 +
  10.115 +  i = OSContainer::cpu_quota();
  10.116 +  st->print("cpu_quota: %d\n", i);
  10.117 +
  10.118 +  i = OSContainer::cpu_period();
  10.119 +  st->print("cpu_period: %d\n", i);
  10.120 +
  10.121 +  i = OSContainer::cpu_shares();
  10.122 +  st->print("cpu_shares: %d\n", i);
  10.123 +
  10.124 +  jlong j = OSContainer::memory_limit_in_bytes();
  10.125 +  st->print("memory_limit_in_bytes: " JLONG_FORMAT "\n", j);
  10.126 +
  10.127 +  j = OSContainer::memory_and_swap_limit_in_bytes();
  10.128 +  st->print("memory_and_swap_limit_in_bytes: " JLONG_FORMAT "\n", j);
  10.129 +
  10.130 +  j = OSContainer::memory_soft_limit_in_bytes();
  10.131 +  st->print("memory_soft_limit_in_bytes: " JLONG_FORMAT "\n", j);
  10.132 +
  10.133 +  j = OSContainer::OSContainer::memory_usage_in_bytes();
  10.134 +  st->print("memory_usage_in_bytes: " JLONG_FORMAT "\n", j);
  10.135 +
  10.136 +  j = OSContainer::OSContainer::memory_max_usage_in_bytes();
  10.137 +  st->print("memory_max_usage_in_bytes: " JLONG_FORMAT "\n", j);
  10.138 +  st->cr();
  10.139 +}
  10.140 +
  10.141  void os::print_memory_info(outputStream* st) {
  10.142  
  10.143    st->print("Memory:");
  10.144 @@ -4956,6 +5059,10 @@
  10.145    }
  10.146  }
  10.147  
  10.148 +void os::pd_init_container_support() {
  10.149 +  OSContainer::init();
  10.150 +}
  10.151 +
  10.152  // this is called _after_ the global arguments have been parsed
  10.153  jint os::init_2(void)
  10.154  {
  10.155 @@ -5136,7 +5243,7 @@
  10.156  // sched_getaffinity gives an accurate answer as it accounts for cpusets.
  10.157  // If anything goes wrong we fallback to returning the number of online
  10.158  // processors - which can be greater than the number available to the process.
  10.159 -int os::active_processor_count() {
  10.160 +int os::Linux::active_processor_count() {
  10.161    cpu_set_t cpus;  // can represent at most 1024 (CPU_SETSIZE) processors
  10.162    int cpus_size = sizeof(cpu_set_t);
  10.163    int cpu_count = 0;
  10.164 @@ -5154,10 +5261,48 @@
  10.165              "which may exceed available processors", strerror(errno), cpu_count);
  10.166    }
  10.167  
  10.168 -  assert(cpu_count > 0 && cpu_count <= processor_count(), "sanity check");
  10.169 +  assert(cpu_count > 0 && cpu_count <= os::processor_count(), "sanity check");
  10.170    return cpu_count;
  10.171  }
  10.172  
  10.173 +// Determine the active processor count from one of
  10.174 +// three different sources:
  10.175 +//
  10.176 +// 1. User option -XX:ActiveProcessorCount
  10.177 +// 2. kernel os calls (sched_getaffinity or sysconf(_SC_NPROCESSORS_ONLN)
  10.178 +// 3. extracted from cgroup cpu subsystem (shares and quotas)
  10.179 +//
  10.180 +// Option 1, if specified, will always override.
  10.181 +// If the cgroup subsystem is active and configured, we
  10.182 +// will return the min of the cgroup and option 2 results.
  10.183 +// This is required since tools, such as numactl, that
  10.184 +// alter cpu affinity do not update cgroup subsystem
  10.185 +// cpuset configuration files.
  10.186 +int os::active_processor_count() {
  10.187 +  // User has overridden the number of active processors
  10.188 +  if (ActiveProcessorCount > 0) {
  10.189 +    if (PrintActiveCpus) {
  10.190 +      tty->print_cr("active_processor_count: "
  10.191 +                    "active processor count set by user : %d",
  10.192 +                    ActiveProcessorCount);
  10.193 +    }
  10.194 +    return ActiveProcessorCount;
  10.195 +  }
  10.196 +
  10.197 +  int active_cpus;
  10.198 +  if (OSContainer::is_containerized()) {
  10.199 +    active_cpus = OSContainer::active_processor_count();
  10.200 +    if (PrintActiveCpus) {
  10.201 +      tty->print_cr("active_processor_count: determined by OSContainer: %d",
  10.202 +                     active_cpus);
  10.203 +    }
  10.204 +  } else {
  10.205 +    active_cpus = os::Linux::active_processor_count();
  10.206 +  }
  10.207 +
  10.208 +  return active_cpus;
  10.209 +}
  10.210 +
  10.211  void os::set_native_thread_name(const char *name) {
  10.212    // Not yet implemented.
  10.213    return;
    11.1 --- a/src/os/linux/vm/os_linux.hpp	Mon Jul 09 05:53:08 2018 -0700
    11.2 +++ b/src/os/linux/vm/os_linux.hpp	Mon Jul 09 15:45:22 2018 +0000
    11.3 @@ -35,6 +35,7 @@
    11.4  
    11.5  class Linux {
    11.6    friend class os;
    11.7 +  friend class OSContainer;
    11.8    friend class TestReserveMemorySpecial;
    11.9  
   11.10    // For signal-chaining
   11.11 @@ -79,6 +80,9 @@
   11.12  
   11.13    static julong available_memory();
   11.14    static julong physical_memory() { return _physical_memory; }
   11.15 +  static void set_physical_memory(julong phys_mem) { _physical_memory = phys_mem; }
   11.16 +  static int active_processor_count();
   11.17 +
   11.18    static void initialize_system_info();
   11.19  
   11.20    static int commit_memory_impl(char* addr, size_t bytes, bool exec);
   11.21 @@ -116,6 +120,7 @@
   11.22    static bool release_memory_special_huge_tlbfs(char* base, size_t bytes);
   11.23  
   11.24    static void print_full_memory_info(outputStream* st);
   11.25 +  static void print_container_info(outputStream* st);
   11.26    static void print_distro_info(outputStream* st);
   11.27    static void print_libversion_info(outputStream* st);
   11.28  
    12.1 --- a/src/os/solaris/vm/os_solaris.cpp	Mon Jul 09 05:53:08 2018 -0700
    12.2 +++ b/src/os/solaris/vm/os_solaris.cpp	Mon Jul 09 15:45:22 2018 +0000
    12.3 @@ -359,6 +359,16 @@
    12.4  }
    12.5  
    12.6  int os::active_processor_count() {
    12.7 +  // User has overridden the number of active processors
    12.8 +  if (ActiveProcessorCount > 0) {
    12.9 +    if (Verbose) {
   12.10 +      tty->print_cr("active_processor_count: "
   12.11 +                    "active processor count set by user : %d",
   12.12 +                     ActiveProcessorCount);
   12.13 +    }
   12.14 +    return ActiveProcessorCount;
   12.15 +  }
   12.16 +
   12.17    int online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
   12.18    pid_t pid = getpid();
   12.19    psetid_t pset = PS_NONE;
    13.1 --- a/src/os/windows/vm/os_windows.cpp	Mon Jul 09 05:53:08 2018 -0700
    13.2 +++ b/src/os/windows/vm/os_windows.cpp	Mon Jul 09 15:45:22 2018 +0000
    13.3 @@ -716,6 +716,16 @@
    13.4  #endif
    13.5  
    13.6  int os::active_processor_count() {
    13.7 +  // User has overridden the number of active processors
    13.8 +  if (ActiveProcessorCount > 0) {
    13.9 +    if (PrintActiveCpus) {
   13.10 +      tty->print_cr("active_processor_count: "
   13.11 +                    "active processor count set by user : %d",
   13.12 +                     ActiveProcessorCount);
   13.13 +    }
   13.14 +    return ActiveProcessorCount;
   13.15 +  }
   13.16 +
   13.17    DWORD_PTR lpProcessAffinityMask = 0;
   13.18    DWORD_PTR lpSystemAffinityMask = 0;
   13.19    int proc_count = processor_count();
    14.1 --- a/src/share/vm/runtime/arguments.cpp	Mon Jul 09 05:53:08 2018 -0700
    14.2 +++ b/src/share/vm/runtime/arguments.cpp	Mon Jul 09 15:45:22 2018 +0000
    14.3 @@ -1,5 +1,5 @@
    14.4  /*
    14.5 - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
    14.6 + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
    14.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.8   *
    14.9   * This code is free software; you can redistribute it and/or modify it
   14.10 @@ -1801,20 +1801,34 @@
   14.11      }
   14.12    }
   14.13  
   14.14 +  // Convert Fraction to Precentage values
   14.15 +  if (FLAG_IS_DEFAULT(MaxRAMPercentage) &&
   14.16 +      !FLAG_IS_DEFAULT(MaxRAMFraction))
   14.17 +    MaxRAMPercentage = 100.0 / MaxRAMFraction;
   14.18 +
   14.19 +   if (FLAG_IS_DEFAULT(MinRAMPercentage) &&
   14.20 +       !FLAG_IS_DEFAULT(MinRAMFraction))
   14.21 +     MinRAMPercentage = 100.0 / MinRAMFraction;
   14.22 +
   14.23 +   if (FLAG_IS_DEFAULT(InitialRAMPercentage) &&
   14.24 +       !FLAG_IS_DEFAULT(InitialRAMFraction))
   14.25 +     InitialRAMPercentage = 100.0 / InitialRAMFraction;
   14.26 +
   14.27    // If the maximum heap size has not been set with -Xmx,
   14.28    // then set it as fraction of the size of physical memory,
   14.29    // respecting the maximum and minimum sizes of the heap.
   14.30    if (FLAG_IS_DEFAULT(MaxHeapSize)) {
   14.31 -    julong reasonable_max = phys_mem / MaxRAMFraction;
   14.32 -
   14.33 -    if (phys_mem <= MaxHeapSize * MinRAMFraction) {
   14.34 +    julong reasonable_max = (julong)((phys_mem * MaxRAMPercentage) / 100);
   14.35 +    const julong reasonable_min = (julong)((phys_mem * MinRAMPercentage) / 100);
   14.36 +    if (reasonable_min < MaxHeapSize) {
   14.37        // Small physical memory, so use a minimum fraction of it for the heap
   14.38 -      reasonable_max = phys_mem / MinRAMFraction;
   14.39 +      reasonable_max = reasonable_min;
   14.40      } else {
   14.41        // Not-small physical memory, so require a heap at least
   14.42        // as large as MaxHeapSize
   14.43        reasonable_max = MAX2(reasonable_max, (julong)MaxHeapSize);
   14.44      }
   14.45 +
   14.46      if (!FLAG_IS_DEFAULT(ErgoHeapSizeLimit) && ErgoHeapSizeLimit != 0) {
   14.47        // Limit the heap size to ErgoHeapSizeLimit
   14.48        reasonable_max = MIN2(reasonable_max, (julong)ErgoHeapSizeLimit);
   14.49 @@ -1856,7 +1870,7 @@
   14.50      reasonable_minimum = limit_by_allocatable_memory(reasonable_minimum);
   14.51  
   14.52      if (InitialHeapSize == 0) {
   14.53 -      julong reasonable_initial = phys_mem / InitialRAMFraction;
   14.54 +      julong reasonable_initial = (julong)((phys_mem * InitialRAMPercentage) / 100);
   14.55  
   14.56        reasonable_initial = MAX3(reasonable_initial, reasonable_minimum, (julong)min_heap_size());
   14.57        reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize);
   14.58 @@ -1881,6 +1895,94 @@
   14.59    }
   14.60  }
   14.61  
   14.62 +// This option inspects the machine and attempts to set various
   14.63 +// parameters to be optimal for long-running, memory allocation
   14.64 +// intensive jobs.  It is intended for machines with large
   14.65 +// amounts of cpu and memory.
   14.66 +jint Arguments::set_aggressive_heap_flags() {
   14.67 +  // initHeapSize is needed since _initial_heap_size is 4 bytes on a 32 bit
   14.68 +  // VM, but we may not be able to represent the total physical memory
   14.69 +  // available (like having 8gb of memory on a box but using a 32bit VM).
   14.70 +  // Thus, we need to make sure we're using a julong for intermediate
   14.71 +  // calculations.
   14.72 +  julong initHeapSize;
   14.73 +  julong total_memory = os::physical_memory();
   14.74 +
   14.75 +  if (total_memory < (julong) 256 * M) {
   14.76 +    jio_fprintf(defaultStream::error_stream(),
   14.77 +            "You need at least 256mb of memory to use -XX:+AggressiveHeap\n");
   14.78 +    vm_exit(1);
   14.79 +  }
   14.80 +
   14.81 +  // The heap size is half of available memory, or (at most)
   14.82 +  // all of possible memory less 160mb (leaving room for the OS
   14.83 +  // when using ISM).  This is the maximum; because adaptive sizing
   14.84 +  // is turned on below, the actual space used may be smaller.
   14.85 +
   14.86 +  initHeapSize = MIN2(total_memory / (julong) 2,
   14.87 +                      total_memory - (julong) 160 * M);
   14.88 +
   14.89 +  initHeapSize = limit_by_allocatable_memory(initHeapSize);
   14.90 +
   14.91 +  if (FLAG_IS_DEFAULT(MaxHeapSize)) {
   14.92 +    FLAG_SET_CMDLINE(uintx, MaxHeapSize, initHeapSize);
   14.93 +    FLAG_SET_CMDLINE(uintx, InitialHeapSize, initHeapSize);
   14.94 +    // Currently the minimum size and the initial heap sizes are the same.
   14.95 +    set_min_heap_size(initHeapSize);
   14.96 +  }
   14.97 +  if (FLAG_IS_DEFAULT(NewSize)) {
   14.98 +    // Make the young generation 3/8ths of the total heap.
   14.99 +    FLAG_SET_CMDLINE(uintx, NewSize,
  14.100 +            ((julong) MaxHeapSize / (julong) 8) * (julong) 3);
  14.101 +    FLAG_SET_CMDLINE(uintx, MaxNewSize, NewSize);
  14.102 +  }
  14.103 +
  14.104 +#ifndef _ALLBSD_SOURCE  // UseLargePages is not yet supported on BSD.
  14.105 +  FLAG_SET_DEFAULT(UseLargePages, true);
  14.106 +#endif
  14.107 +
  14.108 +  // Increase some data structure sizes for efficiency
  14.109 +  FLAG_SET_CMDLINE(uintx, BaseFootPrintEstimate, MaxHeapSize);
  14.110 +  FLAG_SET_CMDLINE(bool, ResizeTLAB, false);
  14.111 +  FLAG_SET_CMDLINE(uintx, TLABSize, 256 * K);
  14.112 +
  14.113 +  // See the OldPLABSize comment below, but replace 'after promotion'
  14.114 +  // with 'after copying'.  YoungPLABSize is the size of the survivor
  14.115 +  // space per-gc-thread buffers.  The default is 4kw.
  14.116 +  FLAG_SET_CMDLINE(uintx, YoungPLABSize, 256 * K);     // Note: this is in words
  14.117 +
  14.118 +  // OldPLABSize is the size of the buffers in the old gen that
  14.119 +  // UseParallelGC uses to promote live data that doesn't fit in the
  14.120 +  // survivor spaces.  At any given time, there's one for each gc thread.
  14.121 +  // The default size is 1kw. These buffers are rarely used, since the
  14.122 +  // survivor spaces are usually big enough.  For specjbb, however, there
  14.123 +  // are occasions when there's lots of live data in the young gen
  14.124 +  // and we end up promoting some of it.  We don't have a definite
  14.125 +  // explanation for why bumping OldPLABSize helps, but the theory
  14.126 +  // is that a bigger PLAB results in retaining something like the
  14.127 +  // original allocation order after promotion, which improves mutator
  14.128 +  // locality.  A minor effect may be that larger PLABs reduce the
  14.129 +  // number of PLAB allocation events during gc.  The value of 8kw
  14.130 +  // was arrived at by experimenting with specjbb.
  14.131 +  FLAG_SET_CMDLINE(uintx, OldPLABSize, 8 * K);      // Note: this is in words
  14.132 +
  14.133 +  // Enable parallel GC and adaptive generation sizing
  14.134 +  FLAG_SET_CMDLINE(bool, UseParallelGC, true);
  14.135 +
  14.136 +  // Encourage steady state memory management
  14.137 +  FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100);
  14.138 +
  14.139 +  // This appears to improve mutator locality
  14.140 +  FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false);
  14.141 +
  14.142 +  // Get around early Solaris scheduling bug
  14.143 +  // (affinity vs other jobs on system)
  14.144 +  // but disallow DR and offlining (5008695).
  14.145 +  FLAG_SET_CMDLINE(bool, BindGCTaskThreadsToCPUs, true);
  14.146 +
  14.147 +  return JNI_OK;
  14.148 +}
  14.149 +
  14.150  // This must be called after ergonomics because we want bytecode rewriting
  14.151  // if the server compiler is used, or if UseSharedSpaces is disabled.
  14.152  void Arguments::set_bytecode_flags() {
  14.153 @@ -2644,6 +2746,14 @@
  14.154      return result;
  14.155    }
  14.156  
  14.157 +  // We need to ensure processor and memory resources have been properly
  14.158 +  // configured - which may rely on arguments we just processed - before
  14.159 +  // doing the final argument processing. Any argument processing that
  14.160 +  // needs to know about processor and memory resources must occur after
  14.161 +  // this point.
  14.162 +
  14.163 +  os::init_container_support();
  14.164 +
  14.165    // Do final processing now that all arguments have been parsed
  14.166    result = finalize_vm_init_args(&scp, scp_assembly_required);
  14.167    if (result != JNI_OK) {
  14.168 @@ -3117,94 +3227,6 @@
  14.169        _exit_hook = CAST_TO_FN_PTR(exit_hook_t, option->extraInfo);
  14.170      } else if (match_option(option, "abort", &tail)) {
  14.171        _abort_hook = CAST_TO_FN_PTR(abort_hook_t, option->extraInfo);
  14.172 -    // -XX:+AggressiveHeap
  14.173 -    } else if (match_option(option, "-XX:+AggressiveHeap", &tail)) {
  14.174 -
  14.175 -      // This option inspects the machine and attempts to set various
  14.176 -      // parameters to be optimal for long-running, memory allocation
  14.177 -      // intensive jobs.  It is intended for machines with large
  14.178 -      // amounts of cpu and memory.
  14.179 -
  14.180 -      // initHeapSize is needed since _initial_heap_size is 4 bytes on a 32 bit
  14.181 -      // VM, but we may not be able to represent the total physical memory
  14.182 -      // available (like having 8gb of memory on a box but using a 32bit VM).
  14.183 -      // Thus, we need to make sure we're using a julong for intermediate
  14.184 -      // calculations.
  14.185 -      julong initHeapSize;
  14.186 -      julong total_memory = os::physical_memory();
  14.187 -
  14.188 -      if (total_memory < (julong)256*M) {
  14.189 -        jio_fprintf(defaultStream::error_stream(),
  14.190 -                    "You need at least 256mb of memory to use -XX:+AggressiveHeap\n");
  14.191 -        vm_exit(1);
  14.192 -      }
  14.193 -
  14.194 -      // The heap size is half of available memory, or (at most)
  14.195 -      // all of possible memory less 160mb (leaving room for the OS
  14.196 -      // when using ISM).  This is the maximum; because adaptive sizing
  14.197 -      // is turned on below, the actual space used may be smaller.
  14.198 -
  14.199 -      initHeapSize = MIN2(total_memory / (julong)2,
  14.200 -                          total_memory - (julong)160*M);
  14.201 -
  14.202 -      initHeapSize = limit_by_allocatable_memory(initHeapSize);
  14.203 -
  14.204 -      if (FLAG_IS_DEFAULT(MaxHeapSize)) {
  14.205 -         FLAG_SET_CMDLINE(uintx, MaxHeapSize, initHeapSize);
  14.206 -         FLAG_SET_CMDLINE(uintx, InitialHeapSize, initHeapSize);
  14.207 -         // Currently the minimum size and the initial heap sizes are the same.
  14.208 -         set_min_heap_size(initHeapSize);
  14.209 -      }
  14.210 -      if (FLAG_IS_DEFAULT(NewSize)) {
  14.211 -         // Make the young generation 3/8ths of the total heap.
  14.212 -         FLAG_SET_CMDLINE(uintx, NewSize,
  14.213 -                                ((julong)MaxHeapSize / (julong)8) * (julong)3);
  14.214 -         FLAG_SET_CMDLINE(uintx, MaxNewSize, NewSize);
  14.215 -      }
  14.216 -
  14.217 -#ifndef _ALLBSD_SOURCE  // UseLargePages is not yet supported on BSD.
  14.218 -      FLAG_SET_DEFAULT(UseLargePages, true);
  14.219 -#endif
  14.220 -
  14.221 -      // Increase some data structure sizes for efficiency
  14.222 -      FLAG_SET_CMDLINE(uintx, BaseFootPrintEstimate, MaxHeapSize);
  14.223 -      FLAG_SET_CMDLINE(bool, ResizeTLAB, false);
  14.224 -      FLAG_SET_CMDLINE(uintx, TLABSize, 256*K);
  14.225 -
  14.226 -      // See the OldPLABSize comment below, but replace 'after promotion'
  14.227 -      // with 'after copying'.  YoungPLABSize is the size of the survivor
  14.228 -      // space per-gc-thread buffers.  The default is 4kw.
  14.229 -      FLAG_SET_CMDLINE(uintx, YoungPLABSize, 256*K);      // Note: this is in words
  14.230 -
  14.231 -      // OldPLABSize is the size of the buffers in the old gen that
  14.232 -      // UseParallelGC uses to promote live data that doesn't fit in the
  14.233 -      // survivor spaces.  At any given time, there's one for each gc thread.
  14.234 -      // The default size is 1kw. These buffers are rarely used, since the
  14.235 -      // survivor spaces are usually big enough.  For specjbb, however, there
  14.236 -      // are occasions when there's lots of live data in the young gen
  14.237 -      // and we end up promoting some of it.  We don't have a definite
  14.238 -      // explanation for why bumping OldPLABSize helps, but the theory
  14.239 -      // is that a bigger PLAB results in retaining something like the
  14.240 -      // original allocation order after promotion, which improves mutator
  14.241 -      // locality.  A minor effect may be that larger PLABs reduce the
  14.242 -      // number of PLAB allocation events during gc.  The value of 8kw
  14.243 -      // was arrived at by experimenting with specjbb.
  14.244 -      FLAG_SET_CMDLINE(uintx, OldPLABSize, 8*K);  // Note: this is in words
  14.245 -
  14.246 -      // Enable parallel GC and adaptive generation sizing
  14.247 -      FLAG_SET_CMDLINE(bool, UseParallelGC, true);
  14.248 -
  14.249 -      // Encourage steady state memory management
  14.250 -      FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100);
  14.251 -
  14.252 -      // This appears to improve mutator locality
  14.253 -      FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false);
  14.254 -
  14.255 -      // Get around early Solaris scheduling bug
  14.256 -      // (affinity vs other jobs on system)
  14.257 -      // but disallow DR and offlining (5008695).
  14.258 -      FLAG_SET_CMDLINE(bool, BindGCTaskThreadsToCPUs, true);
  14.259 -
  14.260      } else if (match_option(option, "-XX:+NeverTenure", &tail)) {
  14.261        // The last option must always win.
  14.262        FLAG_SET_CMDLINE(bool, AlwaysTenure, false);
  14.263 @@ -3605,6 +3627,15 @@
  14.264      return JNI_ERR;
  14.265    }
  14.266  
  14.267 +  // This must be done after all arguments have been processed
  14.268 +  // and the container support has been initialized since AggressiveHeap
  14.269 +  // relies on the amount of total memory available.
  14.270 +  if (AggressiveHeap) {
  14.271 +    jint result = set_aggressive_heap_flags();
  14.272 +    if (result != JNI_OK) {
  14.273 +      return result;
  14.274 +    }
  14.275 +  }
  14.276    // This must be done after all arguments have been processed.
  14.277    // java_compiler() true means set to "NONE" or empty.
  14.278    if (java_compiler() && !xdebug_mode()) {
    15.1 --- a/src/share/vm/runtime/arguments.hpp	Mon Jul 09 05:53:08 2018 -0700
    15.2 +++ b/src/share/vm/runtime/arguments.hpp	Mon Jul 09 15:45:22 2018 +0000
    15.3 @@ -1,5 +1,5 @@
    15.4  /*
    15.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
    15.6 + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
    15.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.8   *
    15.9   * This code is free software; you can redistribute it and/or modify it
   15.10 @@ -365,6 +365,8 @@
   15.11    // Aggressive optimization flags.
   15.12    static void set_aggressive_opts_flags();
   15.13  
   15.14 +  static jint set_aggressive_heap_flags();
   15.15 +
   15.16    // Argument parsing
   15.17    static void do_pd_flag_adjustments();
   15.18    static bool parse_argument(const char* arg, Flag::Flags origin);
    16.1 --- a/src/share/vm/runtime/globals.hpp	Mon Jul 09 05:53:08 2018 -0700
    16.2 +++ b/src/share/vm/runtime/globals.hpp	Mon Jul 09 15:45:22 2018 +0000
    16.3 @@ -2068,13 +2068,23 @@
    16.4    product_pd(uint64_t, MaxRAM,                                              \
    16.5            "Real memory size (in bytes) used to set maximum heap size")      \
    16.6                                                                              \
    16.7 +  product(bool, AggressiveHeap, false,                                      \
    16.8 +          "Optimize heap options for long-running memory intensive apps")   \
    16.9 +                                                                            \
   16.10    product(uintx, ErgoHeapSizeLimit, 0,                                      \
   16.11            "Maximum ergonomically set heap size (in bytes); zero means use " \
   16.12 -          "MaxRAM / MaxRAMFraction")                                        \
   16.13 +          "MaxRAM * MaxRAMPercentage / 100")                                \
   16.14                                                                              \
   16.15    experimental(bool, UseCGroupMemoryLimitForHeap, false,                    \
   16.16            "Use CGroup memory limit as physical memory limit for heap "      \
   16.17 -          "sizing")                                                         \
   16.18 +          "sizing"                                                          \
   16.19 +          "Deprecated, replaced by container support")                      \
   16.20 +                                                                            \
   16.21 +  diagnostic(bool, PrintContainerInfo, false,                               \
   16.22 +          "Print container related information")                            \
   16.23 +                                                                            \
   16.24 +  diagnostic(bool, PrintActiveCpus, false,                                  \
   16.25 +           "Print the number of CPUs detected in os::active_processor_count") \
   16.26                                                                              \
   16.27    product(uintx, MaxRAMFraction, 4,                                         \
   16.28            "Maximum fraction (1/n) of real memory used for maximum heap "    \
   16.29 @@ -2091,6 +2101,19 @@
   16.30    product(uintx, InitialRAMFraction, 64,                                    \
   16.31            "Fraction (1/n) of real memory used for initial heap size")       \
   16.32                                                                              \
   16.33 +  product(double, MaxRAMPercentage, 25.0,                                   \
   16.34 +          "Maximum percentage of real memory used for maximum heap size")   \
   16.35 +                                                                            \
   16.36 +  product(double, MinRAMPercentage, 50.0,                                   \
   16.37 +          "Minimum percentage of real memory used for maximum heap"         \
   16.38 +          "size on systems with small physical memory size")                \
   16.39 +                                                                            \
   16.40 +  product(double, InitialRAMPercentage, 1.5625,                             \
   16.41 +          "Percentage of real memory used for initial heap size")           \
   16.42 +                                                                            \
   16.43 +  product(intx, ActiveProcessorCount, -1,                                   \
   16.44 +          "Specify the CPU count the VM should use and report as active")   \
   16.45 +                                                                            \
   16.46    develop(uintx, MaxVirtMemFraction, 2,                                     \
   16.47            "Maximum fraction (1/n) of virtual memory used for ergonomically "\
   16.48            "determining maximum heap size")                                  \
    17.1 --- a/src/share/vm/runtime/os.hpp	Mon Jul 09 05:53:08 2018 -0700
    17.2 +++ b/src/share/vm/runtime/os.hpp	Mon Jul 09 15:45:22 2018 +0000
    17.3 @@ -152,8 +152,16 @@
    17.4    static size_t page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned);
    17.5  
    17.6    static void initialize_initial_active_processor_count();
    17.7 +
    17.8 +  LINUX_ONLY(static void pd_init_container_support();)
    17.9 +
   17.10   public:
   17.11    static void init(void);                      // Called before command line parsing
   17.12 +
   17.13 +  static void init_container_support() {       // Called during command line parsing.
   17.14 +     LINUX_ONLY(pd_init_container_support();)
   17.15 +  }
   17.16 +
   17.17    static void init_before_ergo(void);          // Called after command line parsing
   17.18                                                 // before VM ergonomics processing.
   17.19    static jint init_2(void);                    // Called after command line parsing
    18.1 --- a/src/share/vm/runtime/thread.cpp	Mon Jul 09 05:53:08 2018 -0700
    18.2 +++ b/src/share/vm/runtime/thread.cpp	Mon Jul 09 15:45:22 2018 +0000
    18.3 @@ -3343,6 +3343,7 @@
    18.4    Arguments::init_version_specific_system_properties();
    18.5  
    18.6    // Parse arguments
    18.7 +  // Note: this internally calls os::init_container_support()
    18.8    jint parse_result = Arguments::parse(args);
    18.9    if (parse_result != JNI_OK) return parse_result;
   18.10  

mercurial