Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/hotspot/share/prims/whitebox.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -94,6 +94,7 @@
#endif // INCLUDE_AOT

#ifdef LINUX
#include "os_linux.hpp"
#include "osContainer_linux.hpp"
#include "cgroupSubsystem_linux.hpp"
#endif
Expand Down Expand Up @@ -2026,6 +2027,18 @@ WB_ENTRY(jboolean, WB_IsContainerized(JNIEnv* env, jobject o))
return false;
WB_END

// Physical memory of the host machine (including containers)
WB_ENTRY(jlong, WB_HostPhysicalMemory(JNIEnv* env, jobject o))
LINUX_ONLY(return os::Linux::physical_memory();)
return os::physical_memory();
WB_END

// Physical swap of the host machine (including containers), Linux only.
WB_ENTRY(jlong, WB_HostPhysicalSwap(JNIEnv* env, jobject o))
LINUX_ONLY(return (jlong)os::Linux::host_swap();)
return -1; // Not used/implemented on other platforms
WB_END

WB_ENTRY(jint, WB_ValidateCgroup(JNIEnv* env,
jobject o,
jstring proc_cgroups,
Expand Down Expand Up @@ -2305,6 +2318,8 @@ static JNINativeMethod methods[] = {
{CC"validateCgroup",
CC"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
(void*)&WB_ValidateCgroup },
{CC"hostPhysicalMemory", CC"()J", (void*)&WB_HostPhysicalMemory },
{CC"hostPhysicalSwap", CC"()J", (void*)&WB_HostPhysicalSwap },
{CC"printOsInfo", CC"()V", (void*)&WB_PrintOsInfo },
{CC"disableElfSectionCache", CC"()V", (void*)&WB_DisableElfSectionCache },
{CC"aotLibrariesCount", CC"()I", (void*)&WB_AotLibrariesCount },
Expand Down
45 changes: 27 additions & 18 deletions test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -35,23 +35,26 @@
* jdk.jartool/sun.tools.jar
* @build AttemptOOM sun.hotspot.WhiteBox PrintContainerInfo CheckOperatingSystemMXBean
* @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
* @run driver TestMemoryAwareness
* @run main/othervm -Xbootclasspath/a:whitebox.jar -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestMemoryAwareness
*/
import jdk.test.lib.containers.docker.Common;
import jdk.test.lib.containers.docker.DockerRunOptions;
import jdk.test.lib.containers.docker.DockerTestUtils;
import sun.hotspot.WhiteBox;
import jdk.test.lib.process.OutputAnalyzer;

import static jdk.test.lib.Asserts.assertNotNull;

public class TestMemoryAwareness {
private static final String imageName = Common.imageName("memory");
private static final WhiteBox wb = WhiteBox.getWhiteBox();

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;
private static String getHostMaxMemory() {
return Long.valueOf(wb.hostPhysicalMemory()).toString();
}

private static String getHostSwap() {
return Long.valueOf(wb.hostPhysicalSwap()).toString();
}

public static void main(String[] args) throws Exception {
Expand Down Expand Up @@ -92,10 +95,9 @@ public static void main(String[] args) throws Exception {
"200M", Integer.toString(((int) Math.pow(2, 20)) * (200 - 100)),
true /* additional cgroup fs mounts */
);
final String hostMaxMem = getHostMaxMemory();
testOperatingSystemMXBeanIgnoresMemLimitExceedingPhysicalMemory(hostMaxMem);
testMetricsIgnoresMemLimitExceedingPhysicalMemory(hostMaxMem);
testContainerMemExceedsPhysical(hostMaxMem);
testOSMXBeanIgnoresMemLimitExceedingPhysicalMemory();
testMetricsExceedingPhysicalMemory();
testContainerMemExceedsPhysical();
} finally {
if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) {
DockerTestUtils.removeDockerImage(imageName);
Expand All @@ -122,9 +124,10 @@ private static void testMemoryLimit(String valueToSet, String expectedTraceValue

// JDK-8292083
// Ensure that Java ignores container memory limit values above the host's physical memory.
private static void testContainerMemExceedsPhysical(final String hostMaxMem)
private static void testContainerMemExceedsPhysical()
throws Exception {
Common.logNewTestCase("container memory limit exceeds physical memory");
String hostMaxMem = getHostMaxMemory();
String badMem = hostMaxMem + "0";
// set a container memory limit to the bad value
DockerRunOptions opts = Common.newOpts(imageName)
Expand Down Expand Up @@ -204,12 +207,17 @@ private static void testOperatingSystemMXBeanAwareness(String memoryAllocation,
.shouldMatch("OperatingSystemMXBean\\.getFreePhysicalMemorySize: [1-9][0-9]+");
// in case of warnings like : "Your kernel does not support swap limit capabilities
// or the cgroup is not mounted. Memory limited without swap."
// the getTotalSwapSpaceSize and getFreeSwapSpaceSize return the system
// values as the container setup isn't supported in that case.
// the getTotalSwapSpaceSize either returns the system (or host) values, or 0
// if a container memory limit is in place and gets detected. A value of 0 is because,
// Metrics.getMemoryLimit() returns the same value as Metrics.getMemoryAndSwapLimit().
//
// getFreeSwapSpaceSize() are a function of what getTotalSwapSpaceSize() returns. Either
// a number > 0, or 0 if getTotalSwapSpaceSize() == 0.
try {
out.shouldContain("OperatingSystemMXBean.getTotalSwapSpaceSize: " + expectedSwap);
} catch(RuntimeException ex) {
out.shouldMatch("OperatingSystemMXBean.getTotalSwapSpaceSize: [0-9]+");
String hostSwap = getHostSwap();
out.shouldMatch("OperatingSystemMXBean.getTotalSwapSpaceSize: (0|" + hostSwap + ")");
}
try {
out.shouldMatch("OperatingSystemMXBean\\.getFreeSwapSpaceSize: [1-9][0-9]+");
Expand All @@ -220,17 +228,18 @@ private static void testOperatingSystemMXBeanAwareness(String memoryAllocation,


// JDK-8292541: Ensure OperatingSystemMXBean ignores container memory limits above the host's physical memory.
private static void testOperatingSystemMXBeanIgnoresMemLimitExceedingPhysicalMemory(final String hostMaxMem)
private static void testOSMXBeanIgnoresMemLimitExceedingPhysicalMemory()
throws Exception {
String hostMaxMem = getHostMaxMemory();
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)
private static void testMetricsExceedingPhysicalMemory()
throws Exception {
Common.logNewTestCase("Metrics ignore container memory limit exceeding physical memory");
String badMem = hostMaxMem + "0";
String badMem = getHostMaxMemory() + "0";
DockerRunOptions opts = Common.newOpts(imageName)
.addJavaOpts("-XshowSettings:system")
.addDockerOpts("--memory", badMem);
Expand Down
4 changes: 3 additions & 1 deletion test/lib/sun/hotspot/WhiteBox.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -542,6 +542,8 @@ public native int validateCgroup(String procCgroups,
String procSelfCgroup,
String procSelfMountinfo);
public native void printOsInfo();
public native long hostPhysicalMemory();
public native long hostPhysicalSwap();

// Decoder
public native void disableElfSectionCache();
Expand Down