mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8217338: [Containers] Improve systemd slice memory limit support
Use hierachical memory limit in addition to memory_limits_in_bytes Reviewed-by: bobv, dholmes
This commit is contained in:
parent
b1ae2d0bf1
commit
73d7e8f86c
4 changed files with 207 additions and 26 deletions
|
@ -25,15 +25,16 @@
|
|||
|
||||
package jdk.internal.platform.cgroupv1;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.platform.cgroupv1.SubSystem.MemorySubSystem;
|
||||
|
||||
public class Metrics implements jdk.internal.platform.Metrics {
|
||||
private SubSystem memory;
|
||||
private MemorySubSystem memory;
|
||||
private SubSystem cpu;
|
||||
private SubSystem cpuacct;
|
||||
private SubSystem cpuset;
|
||||
|
@ -133,7 +134,7 @@ public class Metrics implements jdk.internal.platform.Metrics {
|
|||
for (String subsystemName: subsystemNames) {
|
||||
switch (subsystemName) {
|
||||
case "memory":
|
||||
metric.setMemorySubSystem(new SubSystem(mountentry[3], mountentry[4]));
|
||||
metric.setMemorySubSystem(new MemorySubSystem(mountentry[3], mountentry[4]));
|
||||
break;
|
||||
case "cpuset":
|
||||
metric.setCpuSetSubSystem(new SubSystem(mountentry[3], mountentry[4]));
|
||||
|
@ -195,6 +196,11 @@ public class Metrics implements jdk.internal.platform.Metrics {
|
|||
|
||||
if (subsystem != null) {
|
||||
subsystem.setPath(base);
|
||||
if (subsystem instanceof MemorySubSystem) {
|
||||
MemorySubSystem memorySubSystem = (MemorySubSystem)subsystem;
|
||||
boolean isHierarchial = getHierarchical(memorySubSystem);
|
||||
memorySubSystem.setHierarchical(isHierarchial);
|
||||
}
|
||||
metric.setActiveSubSystems();
|
||||
}
|
||||
if (subsystem2 != null) {
|
||||
|
@ -203,6 +209,11 @@ public class Metrics implements jdk.internal.platform.Metrics {
|
|||
}
|
||||
|
||||
|
||||
private static boolean getHierarchical(MemorySubSystem subsystem) {
|
||||
long hierarchical = SubSystem.getLongValue(subsystem, "memory.use_hierarchy");
|
||||
return hierarchical > 0;
|
||||
}
|
||||
|
||||
private void setActiveSubSystems() {
|
||||
activeSubSystems = true;
|
||||
}
|
||||
|
@ -211,7 +222,7 @@ public class Metrics implements jdk.internal.platform.Metrics {
|
|||
return activeSubSystems;
|
||||
}
|
||||
|
||||
private void setMemorySubSystem(SubSystem memory) {
|
||||
private void setMemorySubSystem(MemorySubSystem memory) {
|
||||
this.memory = memory;
|
||||
}
|
||||
|
||||
|
@ -366,9 +377,29 @@ public class Metrics implements jdk.internal.platform.Metrics {
|
|||
|
||||
public long getMemoryLimit() {
|
||||
long retval = SubSystem.getLongValue(memory, "memory.limit_in_bytes");
|
||||
if (retval > unlimited_minimum) {
|
||||
if (memory.isHierarchical()) {
|
||||
// memory.limit_in_bytes returned unlimited, attempt
|
||||
// hierarchical memory limit
|
||||
String match = "hierarchical_memory_limit";
|
||||
retval = SubSystem.getLongValueMatchingLine(memory,
|
||||
"memory.stat",
|
||||
match,
|
||||
Metrics::convertHierachicalLimitLine);
|
||||
}
|
||||
}
|
||||
return retval > unlimited_minimum ? -1L : retval;
|
||||
}
|
||||
|
||||
public static long convertHierachicalLimitLine(String line) {
|
||||
String[] tokens = line.split("\\s");
|
||||
if (tokens.length == 2) {
|
||||
String strVal = tokens[1];
|
||||
return SubSystem.convertStringToLong(strVal);
|
||||
}
|
||||
return unlimited_minimum + 1; // unlimited
|
||||
}
|
||||
|
||||
public long getMemoryMaxUsage() {
|
||||
return SubSystem.getLongValue(memory, "memory.max_usage_in_bytes");
|
||||
}
|
||||
|
@ -417,6 +448,17 @@ public class Metrics implements jdk.internal.platform.Metrics {
|
|||
|
||||
public long getMemoryAndSwapLimit() {
|
||||
long retval = SubSystem.getLongValue(memory, "memory.memsw.limit_in_bytes");
|
||||
if (retval > unlimited_minimum) {
|
||||
if (memory.isHierarchical()) {
|
||||
// memory.memsw.limit_in_bytes returned unlimited, attempt
|
||||
// hierarchical memory limit
|
||||
String match = "hierarchical_memsw_limit";
|
||||
retval = SubSystem.getLongValueMatchingLine(memory,
|
||||
"memory.stat",
|
||||
match,
|
||||
Metrics::convertHierachicalLimitLine);
|
||||
}
|
||||
}
|
||||
return retval > unlimited_minimum ? -1L : retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,10 +29,11 @@ import java.io.BufferedReader;
|
|||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SubSystem {
|
||||
|
@ -99,10 +100,32 @@ public class SubSystem {
|
|||
|
||||
}
|
||||
|
||||
public static long getLongValueMatchingLine(SubSystem subsystem,
|
||||
String param,
|
||||
String match,
|
||||
Function<String, Long> conversion) {
|
||||
long retval = Metrics.unlimited_minimum + 1; // default unlimited
|
||||
try {
|
||||
List<String> lines = Files.readAllLines(Paths.get(subsystem.path(), param));
|
||||
for (String line: lines) {
|
||||
if (line.contains(match)) {
|
||||
retval = conversion.apply(line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignore. Default is unlimited.
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
public static long getLongValue(SubSystem subsystem, String parm) {
|
||||
String strval = getStringValue(subsystem, parm);
|
||||
long retval = 0;
|
||||
return convertStringToLong(strval);
|
||||
}
|
||||
|
||||
public static long convertStringToLong(String strval) {
|
||||
long retval = 0;
|
||||
if (strval == null) return 0L;
|
||||
|
||||
try {
|
||||
|
@ -215,4 +238,22 @@ public class SubSystem {
|
|||
|
||||
return ints;
|
||||
}
|
||||
|
||||
public static class MemorySubSystem extends SubSystem {
|
||||
|
||||
private boolean hierarchical;
|
||||
|
||||
public MemorySubSystem(String root, String mountPoint) {
|
||||
super(root, mountPoint);
|
||||
}
|
||||
|
||||
boolean isHierarchical() {
|
||||
return hierarchical;
|
||||
}
|
||||
|
||||
void setHierarchical(boolean hierarchical) {
|
||||
this.hierarchical = hierarchical;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue