From 869bad136a30a88ec9812b6a50adaf41753a34a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Hany=C3=A1=C5=A1?= Date: Thu, 18 May 2017 17:15:01 +0200 Subject: [PATCH] Added Linux implementation of method returning free memory even with cached and buffer values. --- .../com/jezhumble/javasysmon/JavaSysMon.java | 10 ++++++ .../jezhumble/javasysmon/LinuxMonitor.java | 32 ++++++++++++++----- .../jezhumble/javasysmon/MacOsXMonitor.java | 1 + .../com/jezhumble/javasysmon/Monitor.java | 8 +++++ .../com/jezhumble/javasysmon/NullMonitor.java | 4 +++ .../jezhumble/javasysmon/SolarisMonitor.java | 1 + .../jezhumble/javasysmon/WindowsMonitor.java | 1 + .../javasysmon/LinuxMonitorTest.java | 6 ++++ src/test/resources/test_meminfo | 4 +-- 9 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/jezhumble/javasysmon/JavaSysMon.java b/src/main/java/com/jezhumble/javasysmon/JavaSysMon.java index cfa3861..1219399 100644 --- a/src/main/java/com/jezhumble/javasysmon/JavaSysMon.java +++ b/src/main/java/com/jezhumble/javasysmon/JavaSysMon.java @@ -192,6 +192,16 @@ public MemoryStats physical() { return monitor.physical(); } + /** + * Gets the physical memory installed, and the amount free + buffers/cache. + * + * @return An object containing the amount of physical + * memory installed, and the amount free + buffers/cache. + */ + public MemoryStats physicalWithBuffersAndCached() { + return monitor.physicalWithBuffersAndCached(); + } + /** * Gets the amount of swap available to the operating system, * and the amount that is free. diff --git a/src/main/java/com/jezhumble/javasysmon/LinuxMonitor.java b/src/main/java/com/jezhumble/javasysmon/LinuxMonitor.java index 6623f93..389b71b 100644 --- a/src/main/java/com/jezhumble/javasysmon/LinuxMonitor.java +++ b/src/main/java/com/jezhumble/javasysmon/LinuxMonitor.java @@ -19,6 +19,10 @@ class LinuxMonitor implements Monitor { Pattern.compile("MemTotal:\\s+(\\d+) kB", Pattern.MULTILINE); private static final Pattern FREE_MEMORY_PATTERN = Pattern.compile("MemFree:\\s+(\\d+) kB", Pattern.MULTILINE); + private static final Pattern BUFFERS_PATTERN = + Pattern.compile("Buffers:\\s+(\\d+) kB", Pattern.MULTILINE); + private static final Pattern CACHED_PATTERN = + Pattern.compile("Cached:\\s+(\\d+) kB", Pattern.MULTILINE); private static final Pattern TOTAL_SWAP_PATTERN = Pattern.compile("SwapTotal:\\s+(\\d+) kB", Pattern.MULTILINE); private static final Pattern FREE_SWAP_PATTERN = @@ -35,6 +39,8 @@ class LinuxMonitor implements Monitor { Pattern.compile("([\\d]*).*"); private static final Pattern DISTRIBUTION = Pattern.compile("DISTRIB_DESCRIPTION=\"(.*)\"", Pattern.MULTILINE); + public static final String PROC_MEMINFO = "/proc/meminfo"; + public static final int TO_BYTE = 1024; private FileUtils fileUtils; private int userHz = 100; // Shouldn't be hardcoded. See below. @@ -66,18 +72,28 @@ public String osName() { } public MemoryStats physical() { - String totalMemory = fileUtils.runRegexOnFile(TOTAL_MEMORY_PATTERN, "/proc/meminfo"); - long total = Long.parseLong(totalMemory) * 1024; - String freeMemory = fileUtils.runRegexOnFile(FREE_MEMORY_PATTERN, "/proc/meminfo"); - long free = Long.parseLong(freeMemory) * 1024; + String totalMemory = fileUtils.runRegexOnFile(TOTAL_MEMORY_PATTERN, PROC_MEMINFO); + long total = Long.parseLong(totalMemory) * TO_BYTE; + String freeMemory = fileUtils.runRegexOnFile(FREE_MEMORY_PATTERN, PROC_MEMINFO); + long free = Long.parseLong(freeMemory) * TO_BYTE; + return new MemoryStats(free, total); + } + + public MemoryStats physicalWithBuffersAndCached() { + String totalMemory = fileUtils.runRegexOnFile(TOTAL_MEMORY_PATTERN, PROC_MEMINFO); + long total = Long.parseLong(totalMemory) * TO_BYTE; + String freeMemory = fileUtils.runRegexOnFile(FREE_MEMORY_PATTERN, PROC_MEMINFO); + String buffers = fileUtils.runRegexOnFile(BUFFERS_PATTERN, PROC_MEMINFO); + String cached = fileUtils.runRegexOnFile(CACHED_PATTERN, PROC_MEMINFO); + long free = (Long.parseLong(freeMemory) + Long.parseLong(buffers) + Long.parseLong(cached)) * TO_BYTE; return new MemoryStats(free, total); } public MemoryStats swap() { - String totalMemory = fileUtils.runRegexOnFile(TOTAL_SWAP_PATTERN, "/proc/meminfo"); - long total = Long.parseLong(totalMemory) * 1024; - String freeMemory = fileUtils.runRegexOnFile(FREE_SWAP_PATTERN, "/proc/meminfo"); - long free = Long.parseLong(freeMemory) * 1024; + String totalMemory = fileUtils.runRegexOnFile(TOTAL_SWAP_PATTERN, PROC_MEMINFO); + long total = Long.parseLong(totalMemory) * TO_BYTE; + String freeMemory = fileUtils.runRegexOnFile(FREE_SWAP_PATTERN, PROC_MEMINFO); + long free = Long.parseLong(freeMemory) * TO_BYTE; return new MemoryStats(free, total); } diff --git a/src/main/java/com/jezhumble/javasysmon/MacOsXMonitor.java b/src/main/java/com/jezhumble/javasysmon/MacOsXMonitor.java index 40ce43f..b22e02b 100644 --- a/src/main/java/com/jezhumble/javasysmon/MacOsXMonitor.java +++ b/src/main/java/com/jezhumble/javasysmon/MacOsXMonitor.java @@ -28,6 +28,7 @@ public String osName() { public native int currentPid(); public native CpuTimes cpuTimes(); public native MemoryStats physical(); + public MemoryStats physicalWithBuffersAndCached(){ throw new UnsupportedOperationException("No implementation for " + osName()); } public native MemoryStats swap(); public native ProcessInfo[] processTable(); public native void killProcess(int pid); diff --git a/src/main/java/com/jezhumble/javasysmon/Monitor.java b/src/main/java/com/jezhumble/javasysmon/Monitor.java index 20919e6..382c3c4 100644 --- a/src/main/java/com/jezhumble/javasysmon/Monitor.java +++ b/src/main/java/com/jezhumble/javasysmon/Monitor.java @@ -60,6 +60,14 @@ public interface Monitor { */ public MemoryStats physical(); + /** + * Gets the physical memory installed, and the amount free + buffers/cache. + * + * @return An object containing the amount of physical + * memory installed, and the amount free + buffers/cache. + */ + public MemoryStats physicalWithBuffersAndCached(); + /** * Gets the amount of swap available to the operating system, * and the amount that is free. diff --git a/src/main/java/com/jezhumble/javasysmon/NullMonitor.java b/src/main/java/com/jezhumble/javasysmon/NullMonitor.java index 2468f96..e5de848 100644 --- a/src/main/java/com/jezhumble/javasysmon/NullMonitor.java +++ b/src/main/java/com/jezhumble/javasysmon/NullMonitor.java @@ -26,6 +26,10 @@ public MemoryStats physical() { return null; } + public MemoryStats physicalWithBuffersAndCached(){ + return null; + } + public MemoryStats swap() { return null; } diff --git a/src/main/java/com/jezhumble/javasysmon/SolarisMonitor.java b/src/main/java/com/jezhumble/javasysmon/SolarisMonitor.java index 98f1280..eb581d5 100644 --- a/src/main/java/com/jezhumble/javasysmon/SolarisMonitor.java +++ b/src/main/java/com/jezhumble/javasysmon/SolarisMonitor.java @@ -50,6 +50,7 @@ public ProcessInfo[] processTable() { public native int currentPid(); public native CpuTimes cpuTimes(); public native MemoryStats physical(); + public MemoryStats physicalWithBuffersAndCached(){ throw new UnsupportedOperationException("No implementation for " + osName()); } public native MemoryStats swap(); public native void killProcess(int pid); } diff --git a/src/main/java/com/jezhumble/javasysmon/WindowsMonitor.java b/src/main/java/com/jezhumble/javasysmon/WindowsMonitor.java index 9ca4cf6..45494dc 100644 --- a/src/main/java/com/jezhumble/javasysmon/WindowsMonitor.java +++ b/src/main/java/com/jezhumble/javasysmon/WindowsMonitor.java @@ -31,6 +31,7 @@ public String osName() { public native long uptimeInSeconds(); public native CpuTimes cpuTimes(); public native MemoryStats physical(); + public MemoryStats physicalWithBuffersAndCached(){ throw new UnsupportedOperationException("No implementation for " + osName()); } public native MemoryStats swap(); public native ProcessInfo[] processTable(); public native void killProcess(int pid); diff --git a/src/test/java/com/jezhumble/javasysmon/LinuxMonitorTest.java b/src/test/java/com/jezhumble/javasysmon/LinuxMonitorTest.java index 3c4be67..299f981 100644 --- a/src/test/java/com/jezhumble/javasysmon/LinuxMonitorTest.java +++ b/src/test/java/com/jezhumble/javasysmon/LinuxMonitorTest.java @@ -19,6 +19,12 @@ public void testShouldRetrieveFreeMemory() { Assert.assertEquals((long)195608, freeMemory/1024); } + public void testShouldRetrieveFreeMemoryWithCachedAndBuffer() { + LinuxMonitor monitor = new LinuxMonitor(new StubFileUtils()); + final long freeMemory = monitor.physicalWithBuffersAndCached().getFreeBytes(); + Assert.assertEquals((long)196038, freeMemory/1024); + } + public void testShouldRetrieveTotalSwap() { LinuxMonitor monitor = new LinuxMonitor(new StubFileUtils()); final long totalSwap = monitor.swap().getTotalBytes(); diff --git a/src/test/resources/test_meminfo b/src/test/resources/test_meminfo index d02f959..49900e6 100644 --- a/src/test/resources/test_meminfo +++ b/src/test/resources/test_meminfo @@ -1,7 +1,7 @@ MemTotal: 368640 kB MemFree: 195608 kB -Buffers: 0 kB -Cached: 0 kB +Buffers: 100 kB +Cached: 330 kB SwapCached: 0 kB Active: 0 kB Inactive: 0 kB