< prev index next >

src/java.base/linux/classes/jdk/internal/platform/cgroupv1/Metrics.java

Print this page
@  rev 54246 : 8217338: [Containers] Improve systemd slice memory limit support
|  Summary: Use hierachical memory limit in addition to memory_limits_in_bytes
~  Reviewed-by: duke


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.internal.platform.cgroupv1;
  27 
  28 import java.io.BufferedReader;
  29 import java.io.IOException;
  30 import java.nio.file.Files;
  31 import java.nio.file.Path;
  32 import java.nio.file.Paths;
  33 import java.util.stream.Stream;
  34 


  35 public class Metrics implements jdk.internal.platform.Metrics {
  36     private SubSystem memory;
  37     private SubSystem cpu;
  38     private SubSystem cpuacct;
  39     private SubSystem cpuset;
  40     private SubSystem blkio;
  41     private boolean activeSubSystems;
  42 
  43     // Values returned larger than this number are unlimited.
  44     static long unlimited_minimum = 0x7FFFFFFFFF000000L;
  45 
  46     private static final Metrics INSTANCE = initContainerSubSystems();
  47 
  48     private static final String PROVIDER_NAME = "cgroupv1";
  49 
  50     private Metrics() {
  51         activeSubSystems = false;
  52     }
  53 
  54     public static Metrics getInstance() {
  55         return INSTANCE;
  56     }


 116         // Return Metrics object if we found any subsystems.
 117         if (metrics.activeSubSystems()) {
 118             return metrics;
 119         }
 120 
 121         return null;
 122     }
 123 
 124     /**
 125      * createSubSystem objects and initialize mount points
 126      */
 127     private static void createSubSystem(Metrics metric, String[] mountentry) {
 128         if (mountentry.length < 5) return;
 129 
 130         Path p = Paths.get(mountentry[4]);
 131         String[] subsystemNames = p.getFileName().toString().split(",");
 132 
 133         for (String subsystemName: subsystemNames) {
 134             switch (subsystemName) {
 135                 case "memory":
 136                     metric.setMemorySubSystem(new SubSystem(mountentry[3], mountentry[4]));
 137                     break;
 138                 case "cpuset":
 139                     metric.setCpuSetSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 140                     break;
 141                 case "cpuacct":
 142                     metric.setCpuAcctSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 143                     break;
 144                 case "cpu":
 145                     metric.setCpuSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 146                     break;
 147                 case "blkio":
 148                     metric.setBlkIOSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 149                     break;
 150                 default:
 151                     // Ignore subsystems that we don't support
 152                     break;
 153             }
 154         }
 155     }
 156 


 178                     subsystem = metric.CpuSubSystem();
 179                     subsystem2 = metric.CpuAcctSubSystem();
 180                     break;
 181                 case "cpuacct":
 182                     subsystem = metric.CpuAcctSubSystem();
 183                     break;
 184                 case "cpu":
 185                     subsystem = metric.CpuSubSystem();
 186                     break;
 187                 case "blkio":
 188                     subsystem = metric.BlkIOSubSystem();
 189                     break;
 190                 // Ignore subsystems that we don't support
 191                 default:
 192                     break;
 193             }
 194         }
 195 
 196         if (subsystem != null) {
 197             subsystem.setPath(base);





 198             metric.setActiveSubSystems();
 199         }
 200         if (subsystem2 != null) {
 201             subsystem2.setPath(base);
 202         }
 203     }
 204 
 205 





 206     private void setActiveSubSystems() {
 207         activeSubSystems = true;
 208     }
 209 
 210     private boolean activeSubSystems() {
 211         return activeSubSystems;
 212     }
 213 
 214     private void setMemorySubSystem(SubSystem memory) {
 215         this.memory = memory;
 216     }
 217 
 218     private void setCpuSubSystem(SubSystem cpu) {
 219         this.cpu = cpu;
 220     }
 221 
 222     private void setCpuAcctSubSystem(SubSystem cpuacct) {
 223         this.cpuacct = cpuacct;
 224     }
 225 
 226     private void setCpuSetSubSystem(SubSystem cpuset) {
 227         this.cpuset = cpuset;
 228     }
 229 
 230     private void setBlkIOSubSystem(SubSystem blkio) {
 231         this.blkio = blkio;
 232     }
 233 
 234     private SubSystem MemorySubSystem() {


 349         return SubSystem.getDoubleValue(cpuset, "cpuset.memory_pressure");
 350     }
 351 
 352     public boolean isCpuSetMemoryPressureEnabled() {
 353         long val = SubSystem.getLongValue(cpuset, "cpuset.memory_pressure_enabled");
 354         return (val == 1);
 355     }
 356 
 357 
 358     /*****************************************************************
 359      * Memory Subsystem
 360      ****************************************************************/
 361 
 362 
 363     public long getMemoryFailCount() {
 364         return SubSystem.getLongValue(memory, "memory.failcnt");
 365     }
 366 
 367     public long getMemoryLimit() {
 368         long retval = SubSystem.getLongValue(memory, "memory.limit_in_bytes");











 369         return retval > unlimited_minimum ? -1L : retval;
 370     }
 371 









 372     public long getMemoryMaxUsage() {
 373         return SubSystem.getLongValue(memory, "memory.max_usage_in_bytes");
 374     }
 375 
 376     public long getMemoryUsage() {
 377         return SubSystem.getLongValue(memory, "memory.usage_in_bytes");
 378     }
 379 
 380     public long getKernelMemoryFailCount() {
 381         return SubSystem.getLongValue(memory, "memory.kmem.failcnt");
 382     }
 383 
 384     public long getKernelMemoryLimit() {
 385         long retval = SubSystem.getLongValue(memory, "memory.kmem.limit_in_bytes");
 386         return retval > unlimited_minimum ? -1L : retval;
 387     }
 388 
 389     public long getKernelMemoryMaxUsage() {
 390         return SubSystem.getLongValue(memory, "memory.kmem.max_usage_in_bytes");
 391     }


 400 
 401     public long getTcpMemoryLimit() {
 402         long retval =  SubSystem.getLongValue(memory, "memory.kmem.tcp.limit_in_bytes");
 403         return retval > unlimited_minimum ? -1L : retval;
 404     }
 405 
 406     public long getTcpMemoryMaxUsage() {
 407         return SubSystem.getLongValue(memory, "memory.kmem.tcp.max_usage_in_bytes");
 408     }
 409 
 410     public long getTcpMemoryUsage() {
 411         return SubSystem.getLongValue(memory, "memory.kmem.tcp.usage_in_bytes");
 412     }
 413 
 414     public long getMemoryAndSwapFailCount() {
 415         return SubSystem.getLongValue(memory, "memory.memsw.failcnt");
 416     }
 417 
 418     public long getMemoryAndSwapLimit() {
 419         long retval = SubSystem.getLongValue(memory, "memory.memsw.limit_in_bytes");











 420         return retval > unlimited_minimum ? -1L : retval;
 421     }
 422 
 423     public long getMemoryAndSwapMaxUsage() {
 424         return SubSystem.getLongValue(memory, "memory.memsw.max_usage_in_bytes");
 425     }
 426 
 427     public long getMemoryAndSwapUsage() {
 428         return SubSystem.getLongValue(memory, "memory.memsw.usage_in_bytes");
 429     }
 430 
 431     public boolean isMemoryOOMKillEnabled() {
 432         long val = SubSystem.getLongEntry(memory, "memory.oom_control", "oom_kill_disable");
 433         return (val == 0);
 434     }
 435 
 436     public long getMemorySoftLimit() {
 437         long retval = SubSystem.getLongValue(memory, "memory.soft_limit_in_bytes");
 438         return retval > unlimited_minimum ? -1L : retval;
 439     }


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.internal.platform.cgroupv1;
  27 

  28 import java.io.IOException;
  29 import java.nio.file.Files;
  30 import java.nio.file.Path;
  31 import java.nio.file.Paths;
  32 import java.util.stream.Stream;
  33 
  34 import jdk.internal.platform.cgroupv1.SubSystem.MemorySubSystem;
  35 
  36 public class Metrics implements jdk.internal.platform.Metrics {
  37     private MemorySubSystem memory;
  38     private SubSystem cpu;
  39     private SubSystem cpuacct;
  40     private SubSystem cpuset;
  41     private SubSystem blkio;
  42     private boolean activeSubSystems;
  43 
  44     // Values returned larger than this number are unlimited.
  45     static long unlimited_minimum = 0x7FFFFFFFFF000000L;
  46 
  47     private static final Metrics INSTANCE = initContainerSubSystems();
  48 
  49     private static final String PROVIDER_NAME = "cgroupv1";
  50 
  51     private Metrics() {
  52         activeSubSystems = false;
  53     }
  54 
  55     public static Metrics getInstance() {
  56         return INSTANCE;
  57     }


 117         // Return Metrics object if we found any subsystems.
 118         if (metrics.activeSubSystems()) {
 119             return metrics;
 120         }
 121 
 122         return null;
 123     }
 124 
 125     /**
 126      * createSubSystem objects and initialize mount points
 127      */
 128     private static void createSubSystem(Metrics metric, String[] mountentry) {
 129         if (mountentry.length < 5) return;
 130 
 131         Path p = Paths.get(mountentry[4]);
 132         String[] subsystemNames = p.getFileName().toString().split(",");
 133 
 134         for (String subsystemName: subsystemNames) {
 135             switch (subsystemName) {
 136                 case "memory":
 137                     metric.setMemorySubSystem(new MemorySubSystem(mountentry[3], mountentry[4]));
 138                     break;
 139                 case "cpuset":
 140                     metric.setCpuSetSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 141                     break;
 142                 case "cpuacct":
 143                     metric.setCpuAcctSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 144                     break;
 145                 case "cpu":
 146                     metric.setCpuSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 147                     break;
 148                 case "blkio":
 149                     metric.setBlkIOSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 150                     break;
 151                 default:
 152                     // Ignore subsystems that we don't support
 153                     break;
 154             }
 155         }
 156     }
 157 


 179                     subsystem = metric.CpuSubSystem();
 180                     subsystem2 = metric.CpuAcctSubSystem();
 181                     break;
 182                 case "cpuacct":
 183                     subsystem = metric.CpuAcctSubSystem();
 184                     break;
 185                 case "cpu":
 186                     subsystem = metric.CpuSubSystem();
 187                     break;
 188                 case "blkio":
 189                     subsystem = metric.BlkIOSubSystem();
 190                     break;
 191                 // Ignore subsystems that we don't support
 192                 default:
 193                     break;
 194             }
 195         }
 196 
 197         if (subsystem != null) {
 198             subsystem.setPath(base);
 199             if (subsystem instanceof MemorySubSystem) {
 200                 MemorySubSystem memorySubSystem = (MemorySubSystem)subsystem;
 201                 boolean isHierarchial = getHierarchical(memorySubSystem);
 202                 memorySubSystem.setHierarchical(isHierarchial);
 203             }
 204             metric.setActiveSubSystems();
 205         }
 206         if (subsystem2 != null) {
 207             subsystem2.setPath(base);
 208         }
 209     }
 210 
 211 
 212     private static boolean getHierarchical(MemorySubSystem subsystem) {
 213         long hierarchical = SubSystem.getLongValue(subsystem, "memory.use_hierarchy");
 214         return hierarchical > 0;
 215     }
 216 
 217     private void setActiveSubSystems() {
 218         activeSubSystems = true;
 219     }
 220 
 221     private boolean activeSubSystems() {
 222         return activeSubSystems;
 223     }
 224 
 225     private void setMemorySubSystem(MemorySubSystem memory) {
 226         this.memory = memory;
 227     }
 228 
 229     private void setCpuSubSystem(SubSystem cpu) {
 230         this.cpu = cpu;
 231     }
 232 
 233     private void setCpuAcctSubSystem(SubSystem cpuacct) {
 234         this.cpuacct = cpuacct;
 235     }
 236 
 237     private void setCpuSetSubSystem(SubSystem cpuset) {
 238         this.cpuset = cpuset;
 239     }
 240 
 241     private void setBlkIOSubSystem(SubSystem blkio) {
 242         this.blkio = blkio;
 243     }
 244 
 245     private SubSystem MemorySubSystem() {


 360         return SubSystem.getDoubleValue(cpuset, "cpuset.memory_pressure");
 361     }
 362 
 363     public boolean isCpuSetMemoryPressureEnabled() {
 364         long val = SubSystem.getLongValue(cpuset, "cpuset.memory_pressure_enabled");
 365         return (val == 1);
 366     }
 367 
 368 
 369     /*****************************************************************
 370      * Memory Subsystem
 371      ****************************************************************/
 372 
 373 
 374     public long getMemoryFailCount() {
 375         return SubSystem.getLongValue(memory, "memory.failcnt");
 376     }
 377 
 378     public long getMemoryLimit() {
 379         long retval = SubSystem.getLongValue(memory, "memory.limit_in_bytes");
 380         if (retval > unlimited_minimum) {
 381             if (memory.isHierarchical()) {
 382                 // memory.limit_in_bytes returned unlimited, attempt
 383                 // hierarchical memory limit
 384                 String match = "hierarchical_memory_limit";
 385                 retval = SubSystem.getLongValueMatchingLine(memory,
 386                                                             "memory.stat",
 387                                                             match,
 388                                                             Metrics::convertHierachicalLimitLine);
 389             }
 390         }
 391         return retval > unlimited_minimum ? -1L : retval;
 392     }
 393 
 394     public static long convertHierachicalLimitLine(String line) {
 395         String[] tokens = line.split("\\s");
 396         if (tokens.length == 2) {
 397             String strVal = tokens[1];
 398             return SubSystem.convertStringToLong(strVal);
 399         }
 400         return unlimited_minimum + 1; // unlimited
 401     }
 402 
 403     public long getMemoryMaxUsage() {
 404         return SubSystem.getLongValue(memory, "memory.max_usage_in_bytes");
 405     }
 406 
 407     public long getMemoryUsage() {
 408         return SubSystem.getLongValue(memory, "memory.usage_in_bytes");
 409     }
 410 
 411     public long getKernelMemoryFailCount() {
 412         return SubSystem.getLongValue(memory, "memory.kmem.failcnt");
 413     }
 414 
 415     public long getKernelMemoryLimit() {
 416         long retval = SubSystem.getLongValue(memory, "memory.kmem.limit_in_bytes");
 417         return retval > unlimited_minimum ? -1L : retval;
 418     }
 419 
 420     public long getKernelMemoryMaxUsage() {
 421         return SubSystem.getLongValue(memory, "memory.kmem.max_usage_in_bytes");
 422     }


 431 
 432     public long getTcpMemoryLimit() {
 433         long retval =  SubSystem.getLongValue(memory, "memory.kmem.tcp.limit_in_bytes");
 434         return retval > unlimited_minimum ? -1L : retval;
 435     }
 436 
 437     public long getTcpMemoryMaxUsage() {
 438         return SubSystem.getLongValue(memory, "memory.kmem.tcp.max_usage_in_bytes");
 439     }
 440 
 441     public long getTcpMemoryUsage() {
 442         return SubSystem.getLongValue(memory, "memory.kmem.tcp.usage_in_bytes");
 443     }
 444 
 445     public long getMemoryAndSwapFailCount() {
 446         return SubSystem.getLongValue(memory, "memory.memsw.failcnt");
 447     }
 448 
 449     public long getMemoryAndSwapLimit() {
 450         long retval = SubSystem.getLongValue(memory, "memory.memsw.limit_in_bytes");
 451         if (retval > unlimited_minimum) {
 452             if (memory.isHierarchical()) {
 453                 // memory.memsw.limit_in_bytes returned unlimited, attempt
 454                 // hierarchical memory limit
 455                 String match = "hierarchical_memsw_limit";
 456                 retval = SubSystem.getLongValueMatchingLine(memory,
 457                                                             "memory.stat",
 458                                                             match,
 459                                                             Metrics::convertHierachicalLimitLine);
 460             }
 461         }
 462         return retval > unlimited_minimum ? -1L : retval;
 463     }
 464 
 465     public long getMemoryAndSwapMaxUsage() {
 466         return SubSystem.getLongValue(memory, "memory.memsw.max_usage_in_bytes");
 467     }
 468 
 469     public long getMemoryAndSwapUsage() {
 470         return SubSystem.getLongValue(memory, "memory.memsw.usage_in_bytes");
 471     }
 472 
 473     public boolean isMemoryOOMKillEnabled() {
 474         long val = SubSystem.getLongEntry(memory, "memory.oom_control", "oom_kill_disable");
 475         return (val == 0);
 476     }
 477 
 478     public long getMemorySoftLimit() {
 479         long retval = SubSystem.getLongValue(memory, "memory.soft_limit_in_bytes");
 480         return retval > unlimited_minimum ? -1L : retval;
 481     }
< prev index next >