aboutsummaryrefslogtreecommitdiff
path: root/spark-common/src/main/java/me
diff options
context:
space:
mode:
Diffstat (limited to 'spark-common/src/main/java/me')
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuInfo.java24
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/memory/MemoryInfo.java67
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/LinuxProc.java79
3 files changed, 148 insertions, 22 deletions
diff --git a/spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuInfo.java b/spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuInfo.java
index a179904..9bbe0f8 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuInfo.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/monitor/cpu/CpuInfo.java
@@ -20,13 +20,8 @@
package me.lucko.spark.common.monitor.cpu;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
+import me.lucko.spark.common.util.LinuxProc;
+
import java.util.regex.Pattern;
/**
@@ -43,8 +38,7 @@ public enum CpuInfo {
* @return the cpu model
*/
public static String queryCpuModel() {
- List<String> cpuInfo = readFile("/proc/cpuinfo");
- for (String line : cpuInfo) {
+ for (String line : LinuxProc.CPUINFO.read()) {
String[] splitLine = SPACE_COLON_SPACE_PATTERN.split(line);
if (splitLine[0].equals("model name") || splitLine[0].equals("Processor")) {
@@ -54,16 +48,4 @@ public enum CpuInfo {
return "";
}
- private static List<String> readFile(String file) {
- Path path = Paths.get(file);
- if (Files.isReadable(path)) {
- try {
- return Files.readAllLines(path, StandardCharsets.UTF_8);
- } catch (IOException e) {
- // ignore
- }
- }
- return new ArrayList<>();
- }
-
}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/monitor/memory/MemoryInfo.java b/spark-common/src/main/java/me/lucko/spark/common/monitor/memory/MemoryInfo.java
index 4ed9b1c..4aa52f4 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/monitor/memory/MemoryInfo.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/monitor/memory/MemoryInfo.java
@@ -20,12 +20,19 @@
package me.lucko.spark.common.monitor.memory;
+import me.lucko.spark.common.util.LinuxProc;
+
import java.lang.management.ManagementFactory;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.ObjectName;
+/**
+ * Utility to query information about system memory usage.
+ */
public enum MemoryInfo {
;
@@ -34,6 +41,9 @@ public enum MemoryInfo {
/** The OperatingSystemMXBean instance */
private static final OperatingSystemMXBean BEAN;
+ /** The format used by entries in /proc/meminfo */
+ private static final Pattern PROC_MEMINFO_VALUE = Pattern.compile("^(\\w+):\\s*(\\d+) kB$");
+
static {
try {
MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
@@ -44,6 +54,8 @@ public enum MemoryInfo {
}
}
+ /* Swap */
+
public static long getUsedSwap() {
return BEAN.getTotalSwapSpaceSize() - BEAN.getFreeSwapSpaceSize();
}
@@ -52,14 +64,67 @@ public enum MemoryInfo {
return BEAN.getTotalSwapSpaceSize();
}
+ /* Physical Memory */
+
public static long getUsedPhysicalMemory() {
- return BEAN.getTotalPhysicalMemorySize() - BEAN.getFreePhysicalMemorySize();
+ return BEAN.getTotalPhysicalMemorySize() - getAvailablePhysicalMemory();
}
public static long getTotalPhysicalMemory() {
return BEAN.getTotalPhysicalMemorySize();
}
+ public static long getAvailablePhysicalMemory() {
+ boolean present = false;
+ long free = 0, buffers = 0, cached = 0, sReclaimable = 0;
+
+ for (String line : LinuxProc.MEMINFO.read()) {
+ Matcher matcher = PROC_MEMINFO_VALUE.matcher(line);
+ if (matcher.matches()) {
+ present = true;
+
+ String label = matcher.group(1);
+ long value = Long.parseLong(matcher.group(2)) * 1024; // kB -> B
+
+ // if MemAvailable is set, just return that
+ if (label.equals("MemAvailable")) {
+ return value;
+ }
+
+ // otherwise, record MemFree, Buffers, Cached and SReclaimable
+ switch (label) {
+ case "MemFree":
+ free = value;
+ break;
+ case "Buffers":
+ buffers = value;
+ break;
+ case "Cached":
+ cached = value;
+ break;
+ case "SReclaimable":
+ sReclaimable = value;
+ break;
+ }
+ }
+ }
+
+ // estimate how much is "available" - not exact but this is probably good enough.
+ // most Linux systems (assuming they have been updated in the last ~8 years) will
+ // have MemAvailable set, and we return that instead if present
+ //
+ // useful ref: https://www.linuxatemyram.com/
+ if (present) {
+ return free + buffers + cached + sReclaimable;
+ }
+
+ // fallback to what the JVM understands as "free"
+ // on non-linux systems, this is probably good enough to estimate what's available
+ return BEAN.getFreePhysicalMemorySize();
+ }
+
+ /* Virtual Memory */
+
public static long getTotalVirtualMemory() {
return BEAN.getCommittedVirtualMemorySize();
}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/LinuxProc.java b/spark-common/src/main/java/me/lucko/spark/common/util/LinuxProc.java
new file mode 100644
index 0000000..0926ae7
--- /dev/null
+++ b/spark-common/src/main/java/me/lucko/spark/common/util/LinuxProc.java
@@ -0,0 +1,79 @@
+/*
+ * This file is part of spark.
+ *
+ * Copyright (c) lucko (Luck) <luck@lucko.me>
+ * Copyright (c) contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package me.lucko.spark.common.util;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Utility for reading from /proc/ on Linux systems.
+ */
+public enum LinuxProc {
+
+ /**
+ * Information about the system CPU.
+ */
+ CPUINFO("/proc/cpuinfo"),
+
+ /**
+ * Information about the system memory.
+ */
+ MEMINFO("/proc/meminfo");
+
+ private final Path path;
+
+ LinuxProc(String path) {
+ this.path = resolvePath(path);
+ }
+
+ private static @Nullable Path resolvePath(String path) {
+ try {
+ Path p = Paths.get(path);
+ if (Files.isReadable(p)) {
+ return p;
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ return null;
+ }
+
+ public @NonNull List<String> read() {
+ if (this.path != null) {
+ try {
+ return Files.readAllLines(this.path, StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+ return Collections.emptyList();
+ }
+
+}