From c72455c80ccb766960d0a4d17cf500afa30d438d Mon Sep 17 00:00:00 2001 From: ffccites <99155080+PDGGK@users.noreply.github.com> Date: Mon, 23 Feb 2026 01:51:38 +0800 Subject: [PATCH] Fix Process resource leak in system metrics collection Add process.waitFor() and process.destroyForcibly() in finally block to prevent zombie processes when collecting system memory and network metrics via Runtime.exec(). Also handle InterruptedException properly by restoring the interrupt flag. Affected files: - SystemMetrics: memory info collection via 'free' command - LinuxNetMetricManager: socket count collection via 'ss' command --- .../metrics/metricsets/net/LinuxNetMetricManager.java | 11 ++++++++++- .../metrics/metricsets/system/SystemMetrics.java | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/LinuxNetMetricManager.java b/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/LinuxNetMetricManager.java index 2c81bc0efc031..e7184adeee32e 100644 --- a/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/LinuxNetMetricManager.java +++ b/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/net/LinuxNetMetricManager.java @@ -218,8 +218,9 @@ private void updateNetStatus() { if (MetricLevel.higherOrEqual(MetricLevel.NORMAL, METRIC_CONFIG.getMetricLevel())) { // update socket num + Process process = null; try { - Process process = Runtime.getRuntime().exec(this.getConnectNumCmd); + process = Runtime.getRuntime().exec(this.getConnectNumCmd); StringBuilder result = new StringBuilder(); try (BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()))) { @@ -228,9 +229,17 @@ private void updateNetStatus() { result.append(line); } } + process.waitFor(); this.connectionNum = Integer.parseInt(result.toString().trim()); } catch (IOException e) { LOGGER.error("Failed to get socket num", e); + } catch (InterruptedException e) { + LOGGER.error("Interrupted while waiting for socket num command", e); + Thread.currentThread().interrupt(); + } finally { + if (process != null) { + process.destroyForcibly(); + } } } } diff --git a/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/system/SystemMetrics.java b/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/system/SystemMetrics.java index 1cacf2bf6f5f7..60a24397b1f7c 100644 --- a/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/system/SystemMetrics.java +++ b/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/metricsets/system/SystemMetrics.java @@ -217,8 +217,9 @@ private void updateLinuxSystemMemInfo() { long time = System.currentTimeMillis(); if (time - lastUpdateTime > MetricConstant.UPDATE_INTERVAL) { lastUpdateTime = time; + Process process = null; try { - Process process = runtime.exec(getSystemMemoryCommand); + process = runtime.exec(getSystemMemoryCommand); StringBuilder result = new StringBuilder(); try (BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()))) { @@ -227,6 +228,7 @@ private void updateLinuxSystemMemInfo() { result.append(line).append("\n"); } } + process.waitFor(); String[] lines = result.toString().trim().split("\n"); // if failed to get result if (lines.length >= 2) { @@ -240,6 +242,13 @@ private void updateLinuxSystemMemInfo() { } } catch (IOException e) { logger.debug("Failed to get memory, because ", e); + } catch (InterruptedException e) { + logger.debug("Interrupted while waiting for memory command", e); + Thread.currentThread().interrupt(); + } finally { + if (process != null) { + process.destroyForcibly(); + } } } }