8292541: [Metrics] Reported memory limit may exceed physical machine memory
Reviewed-by: stuefe, sgehwolf
This commit is contained in:
parent
c74b6d4552
commit
9a0d1e7ce8
src/java.base/linux
test/hotspot/jtreg/containers/docker
@ -121,7 +121,13 @@ public class CgroupMetrics implements Metrics {
|
||||
|
||||
@Override
|
||||
public long getMemoryLimit() {
|
||||
return subsystem.getMemoryLimit();
|
||||
long subsMem = subsystem.getMemoryLimit();
|
||||
// Catch the cgroup memory limit exceeding host physical memory.
|
||||
// Treat this as unlimited.
|
||||
if (subsMem >= getTotalMemorySize0()) {
|
||||
return CgroupSubsystem.LONG_RETVAL_UNLIMITED;
|
||||
}
|
||||
return subsMem;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -178,5 +184,6 @@ public class CgroupMetrics implements Metrics {
|
||||
}
|
||||
|
||||
private static native boolean isUseContainerSupport();
|
||||
private static native long getTotalMemorySize0();
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jvm.h"
|
||||
@ -33,3 +34,10 @@ Java_jdk_internal_platform_CgroupMetrics_isUseContainerSupport(JNIEnv *env, jcla
|
||||
{
|
||||
return JVM_IsUseContainerSupport();
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_jdk_internal_platform_CgroupMetrics_getTotalMemorySize0
|
||||
(JNIEnv *env, jclass ignored)
|
||||
{
|
||||
return sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
|
@ -47,6 +47,13 @@ import static jdk.test.lib.Asserts.assertNotNull;
|
||||
public class TestMemoryAwareness {
|
||||
private static final String imageName = Common.imageName("memory");
|
||||
|
||||
private static String getHostMaxMemory() throws Exception {
|
||||
DockerRunOptions opts = Common.newOpts(imageName);
|
||||
String goodMem = Common.run(opts).firstMatch("total physical memory: (\\d+)", 1);
|
||||
assertNotNull(goodMem, "no match for 'total physical memory' in trace output");
|
||||
return goodMem;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (!DockerTestUtils.canTestDocker()) {
|
||||
return;
|
||||
@ -79,7 +86,10 @@ public class TestMemoryAwareness {
|
||||
"1G", Integer.toString(((int) Math.pow(2, 20)) * 1024),
|
||||
"1500M", Integer.toString(((int) Math.pow(2, 20)) * (1500 - 1024))
|
||||
);
|
||||
testContainerMemExceedsPhysical();
|
||||
final String hostMaxMem = getHostMaxMemory();
|
||||
testOperatingSystemMXBeanIgnoresMemLimitExceedingPhysicalMemory(hostMaxMem);
|
||||
testMetricsIgnoresMemLimitExceedingPhysicalMemory(hostMaxMem);
|
||||
testContainerMemExceedsPhysical(hostMaxMem);
|
||||
} finally {
|
||||
if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) {
|
||||
DockerTestUtils.removeDockerImage(imageName);
|
||||
@ -102,24 +112,16 @@ public class TestMemoryAwareness {
|
||||
|
||||
// JDK-8292083
|
||||
// Ensure that Java ignores container memory limit values above the host's physical memory.
|
||||
private static void testContainerMemExceedsPhysical()
|
||||
private static void testContainerMemExceedsPhysical(final String hostMaxMem)
|
||||
throws Exception {
|
||||
|
||||
Common.logNewTestCase("container memory limit exceeds physical memory");
|
||||
|
||||
DockerRunOptions opts = Common.newOpts(imageName);
|
||||
|
||||
// first run: establish physical memory in test environment and derive
|
||||
// a bad value one power of ten larger
|
||||
String goodMem = Common.run(opts).firstMatch("total physical memory: (\\d+)", 1);
|
||||
assertNotNull(goodMem, "no match for 'total physical memory' in trace output");
|
||||
String badMem = goodMem + "0";
|
||||
|
||||
// second run: set a container memory limit to the bad value
|
||||
opts = Common.newOpts(imageName)
|
||||
String badMem = hostMaxMem + "0";
|
||||
// set a container memory limit to the bad value
|
||||
DockerRunOptions opts = Common.newOpts(imageName)
|
||||
.addDockerOpts("--memory", badMem);
|
||||
|
||||
Common.run(opts)
|
||||
.shouldMatch("container memory limit (ignored: " + badMem + "|unlimited: -1), using host value " + goodMem);
|
||||
.shouldMatch("container memory limit (ignored: " + badMem + "|unlimited: -1), using host value " + hostMaxMem);
|
||||
}
|
||||
|
||||
|
||||
@ -200,4 +202,23 @@ public class TestMemoryAwareness {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// JDK-8292541: Ensure OperatingSystemMXBean ignores container memory limits above the host's physical memory.
|
||||
private static void testOperatingSystemMXBeanIgnoresMemLimitExceedingPhysicalMemory(final String hostMaxMem)
|
||||
throws Exception {
|
||||
String badMem = hostMaxMem + "0";
|
||||
testOperatingSystemMXBeanAwareness(badMem, hostMaxMem, badMem, hostMaxMem);
|
||||
}
|
||||
|
||||
// JDK-8292541: Ensure Metrics ignores container memory limits above the host's physical memory.
|
||||
private static void testMetricsIgnoresMemLimitExceedingPhysicalMemory(final String hostMaxMem)
|
||||
throws Exception {
|
||||
Common.logNewTestCase("Metrics ignore container memory limit exceeding physical memory");
|
||||
String badMem = hostMaxMem + "0";
|
||||
DockerRunOptions opts = Common.newOpts(imageName)
|
||||
.addJavaOpts("-XshowSettings:system")
|
||||
.addDockerOpts("--memory", badMem);
|
||||
|
||||
DockerTestUtils.dockerRunJava(opts).shouldMatch("Memory Limit: Unlimited");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user