Skip to content

Commit 2f3cdc5

Browse files
fmeumcopybara-github
authored andcommitted
Make Bazel's RAM estimate container aware
As of JDK 14, `OperatingSystemMXBean` provides information about system memory that is container-aware. Outside containers, it uses the same mechanisms as Bazel to determine available RAM (`/proc/meminfo` on Linux, `hw.memsize` on macOS) and can thus be used as a drop-in replacement for the custom implementation. A small caveat is that Bazel's macOS RAM estimate was based on converting bytes to "MB" via a divisor of `1000^2` instead of `1024^2`, resulting in a consistent overestimate compared to an identical Linux machine that is now corrected. This opportunity was missed in #16512 since `OperatingSystemMXBean` is based on a complete Java implementation of cgroups handling and doesn't go through the `os::total_memory` or `os::physical_memory` Hotspot functions. RELNOTES[INC]: * On Linux, Bazel's RAM estimate for the host machine is now aware of container resource limits. * On macOS, Bazel no longer consistently overestimates the total RAM by ~5% (`1024^2/1000^2`). * On Windows, Bazel's RAM estimate is now generally more accurate as it is no longer influenced by JVM heuristics. Fixes #3886 Closes #20435. PiperOrigin-RevId: 588718034 Change-Id: I2daafa0567740a1b149ca8756ec27f102129283c
1 parent 18409dc commit 2f3cdc5

File tree

12 files changed

+18
-372
lines changed

12 files changed

+18
-372
lines changed

src/main/java/com/google/devtools/build/lib/actions/BUILD

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -427,18 +427,13 @@ java_library(
427427
name = "localhost_capacity",
428428
srcs = [
429429
"LocalHostCapacity.java",
430-
"LocalHostResourceFallback.java",
431-
"LocalHostResourceManagerDarwin.java",
432-
"LocalHostResourceManagerLinux.java",
430+
"LocalHostResource.java",
433431
"ResourceSet.java",
434432
"ResourceSetOrBuilder.java",
435433
],
436434
deps = [
437435
":exec_exception",
438436
"//src/main/java/com/google/devtools/build/lib/concurrent",
439-
"//src/main/java/com/google/devtools/build/lib/jni",
440-
"//src/main/java/com/google/devtools/build/lib/unix",
441-
"//src/main/java/com/google/devtools/build/lib/unix:procmeminfo_parser",
442437
"//src/main/java/com/google/devtools/build/lib/util:os",
443438
"//src/main/java/com/google/devtools/build/lib/worker:worker_key",
444439
"//src/main/java/com/google/devtools/common/options",

src/main/java/com/google/devtools/build/lib/actions/LocalHostCapacity.java

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import com.google.common.annotations.VisibleForTesting;
1818
import com.google.common.flogger.GoogleLogger;
1919
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
20-
import com.google.devtools.build.lib.util.OS;
2120

2221
/**
2322
* This class estimates the local host's resource capacity.
@@ -26,7 +25,6 @@
2625
public final class LocalHostCapacity {
2726

2827
private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
29-
private static final OS currentOS = OS.getCurrent();
3028
private static ResourceSet localHostCapacity;
3129

3230
private LocalHostCapacity() {}
@@ -39,21 +37,7 @@ public static ResourceSet getLocalHostCapacity() {
3937
}
4038

4139
private static ResourceSet getNewLocalHostCapacity() {
42-
ResourceSet localResources = null;
43-
switch (currentOS) {
44-
case DARWIN:
45-
localResources = LocalHostResourceManagerDarwin.getLocalHostResources();
46-
break;
47-
case LINUX:
48-
localResources = LocalHostResourceManagerLinux.getLocalHostResources();
49-
break;
50-
default:
51-
break;
52-
}
53-
if (localResources == null) {
54-
localResources = LocalHostResourceFallback.getLocalHostResources();
55-
}
56-
40+
ResourceSet localResources = LocalHostResource.get();
5741
logger.atInfo().log(
5842
"Determined local resources: RAM=%dMB, CPU=%.1f",
5943
(int) localResources.getMemoryMb(), localResources.getCpuUsage());

src/main/java/com/google/devtools/build/lib/actions/LocalHostResourceFallback.java renamed to src/main/java/com/google/devtools/build/lib/actions/LocalHostResource.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,28 @@
1414

1515
package com.google.devtools.build.lib.actions;
1616

17-
/**
18-
* This class provide a fallback of the local host's resource capacity.
19-
*/
20-
public class LocalHostResourceFallback {
17+
import com.sun.management.OperatingSystemMXBean;
18+
import java.lang.management.ManagementFactory;
19+
20+
/** This class computes the local host's resource capacity. */
21+
final class LocalHostResource {
2122

22-
/* If /proc/* information is not available, guess based on what the JVM thinks. Anecdotally,
23-
* the JVM picks 0.22 the total available memory as maxMemory (tested on a standard Mac), so
24-
* multiply by 3, and divide by 2^20 because we want megabytes.
25-
*/
2623
private static final ResourceSet DEFAULT_RESOURCES =
2724
ResourceSet.create(
28-
3.0 * (Runtime.getRuntime().maxMemory() >> 20),
25+
// Only com.sun.management.OperatingSystemMXBean provides the total physical memory size.
26+
// This bean is container-aware as of JDK 14.
27+
// https://github.com/openjdk/jdk/commit/7b82266a159ce363708e347aba7e1b0d38206b48
28+
((OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean())
29+
.getTotalPhysicalMemorySize()
30+
/ (1024.0 * 1024.0),
31+
// As of JDK 11, availableProcessors is aware of cgroups as commonly used by containers.
32+
// https://hg.openjdk.java.net/jdk/hs/rev/7f22774a5f42#l6.178
2933
Runtime.getRuntime().availableProcessors(),
3034
Integer.MAX_VALUE);
3135

32-
public static ResourceSet getLocalHostResources() {
36+
public static ResourceSet get() {
3337
return DEFAULT_RESOURCES;
3438
}
39+
40+
private LocalHostResource() {}
3541
}

src/main/java/com/google/devtools/build/lib/actions/LocalHostResourceManagerDarwin.java

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/main/java/com/google/devtools/build/lib/actions/LocalHostResourceManagerLinux.java

Lines changed: 0 additions & 58 deletions
This file was deleted.

src/main/java/com/google/devtools/build/lib/unix/NativePosixSystem.java

Lines changed: 0 additions & 40 deletions
This file was deleted.

src/main/native/darwin/file_jni.cc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,4 @@ ssize_t portable_lgetxattr(const char *path, const char *name, void *value,
113113
return result;
114114
}
115115

116-
int portable_sysctlbyname(const char *name_chars, void *mibp, size_t *sizep) {
117-
return sysctlbyname(name_chars, mibp, sizep, nullptr, 0);
118-
}
119-
120116
} // namespace blaze_jni

src/main/native/unix_jni.cc

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,19 +1282,6 @@ Java_com_google_devtools_build_lib_unix_NativePosixFiles_write(
12821282
free(buf);
12831283
}
12841284

1285-
extern "C" JNIEXPORT jlong JNICALL
1286-
Java_com_google_devtools_build_lib_unix_NativePosixSystem_sysctlbynameGetLong(
1287-
JNIEnv *env, jclass clazz, jstring name) {
1288-
const char *name_chars = GetStringLatin1Chars(env, name);
1289-
int64_t r;
1290-
size_t len = sizeof(r);
1291-
if (portable_sysctlbyname(name_chars, &r, &len) == -1) {
1292-
PostException(env, errno, std::string("sysctlbyname(") + name_chars + ")");
1293-
}
1294-
ReleaseStringLatin1Chars(name_chars);
1295-
return (jlong)r;
1296-
}
1297-
12981285
/*
12991286
* Class: com_google_devtools_build_lib_platform_SleepPreventionModule_SleepPrevention
13001287
* Method: pushDisableSleep

src/main/native/unix_jni.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,6 @@ ssize_t portable_getxattr(const char *path, const char *name, void *value,
8383
ssize_t portable_lgetxattr(const char *path, const char *name, void *value,
8484
size_t size, bool *attr_not_found);
8585

86-
// Run sysctlbyname(3), only available on darwin
87-
int portable_sysctlbyname(const char *name_chars, void *mibp, size_t *sizep);
88-
8986
// Used to surround an region that we want sleep disabled for.
9087
// push_disable_sleep to start the area.
9188
// pop_disable_sleep to end the area.

src/main/native/unix_jni_bsd.cc

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,6 @@ ssize_t portable_lgetxattr(const char *path, const char *name, void *value,
105105
#endif
106106
}
107107

108-
int portable_sysctlbyname(const char *name_chars, void *mibp, size_t *sizep) {
109-
#if defined(HAVE_SYSCTLBYNAME)
110-
return sysctlbyname(name_chars, mibp, sizep, nullptr, 0);
111-
#else
112-
errno = ENOSYS;
113-
return -1;
114-
#endif
115-
}
116-
117108
int portable_push_disable_sleep() {
118109
// Currently not supported.
119110
// https://wiki.freebsd.org/SuspendResume

0 commit comments

Comments
 (0)