|
24 | 24 | */ |
25 | 25 | package com.oracle.svm.core.heap; |
26 | 26 |
|
| 27 | +import java.io.BufferedReader; |
| 28 | +import java.io.FileReader; |
27 | 29 | import java.io.IOException; |
28 | 30 | import java.lang.management.ManagementFactory; |
29 | | -import java.nio.file.Files; |
30 | | -import java.nio.file.Paths; |
| 31 | +import java.nio.charset.StandardCharsets; |
| 32 | +import java.util.ArrayList; |
31 | 33 | import java.util.List; |
32 | 34 | import java.util.concurrent.locks.ReentrantLock; |
33 | 35 |
|
|
44 | 46 | import com.oracle.svm.core.thread.VMOperation; |
45 | 47 | import com.oracle.svm.core.util.UnsignedUtils; |
46 | 48 | import com.oracle.svm.core.util.VMError; |
47 | | - |
48 | 49 | import com.sun.management.OperatingSystemMXBean; |
49 | 50 |
|
50 | 51 | /** |
@@ -117,33 +118,70 @@ public static UnsignedWord size() { |
117 | 118 | return cachedSize; |
118 | 119 | } |
119 | 120 |
|
120 | | - /** |
121 | | - * Returns the amount of used physical memory in bytes, or -1 if not supported yet. |
122 | | - */ |
| 121 | + /** Returns the amount of used physical memory in bytes, or -1 if not supported. */ |
123 | 122 | public static long usedSize() { |
124 | | - // Containerized Linux, Windows and Mac OS X use the OS bean |
125 | | - if ((Containers.isContainerized() && Containers.memoryLimitInBytes() > 0) || |
126 | | - Platform.includedIn(Platform.WINDOWS.class) || |
127 | | - Platform.includedIn(Platform.MACOS.class)) { |
| 123 | + // Windows, macOS, and containerized Linux use the OS bean. |
| 124 | + if (Platform.includedIn(Platform.WINDOWS.class) || |
| 125 | + Platform.includedIn(Platform.MACOS.class) || |
| 126 | + (Containers.isContainerized() && Containers.memoryLimitInBytes() > 0)) { |
128 | 127 | OperatingSystemMXBean osBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); |
129 | 128 | return osBean.getTotalMemorySize() - osBean.getFreeMemorySize(); |
130 | 129 | } |
131 | | - // Non-containerized Linux uses MemAvailable from /proc/meminfo |
| 130 | + |
| 131 | + // Non-containerized Linux uses /proc/meminfo. |
132 | 132 | if (Platform.includedIn(Platform.LINUX.class)) { |
133 | | - try { |
134 | | - List<String> lines = Files.readAllLines(Paths.get("/proc/meminfo")); |
135 | | - for (String line : lines) { |
136 | | - if (!line.contains("MemAvailable")) { |
137 | | - continue; |
138 | | - } |
139 | | - String memAvailable = line.replaceAll("\\D", ""); |
140 | | - if (!memAvailable.isEmpty()) { |
141 | | - return size().rawValue() - Long.parseLong(memAvailable) * K; |
142 | | - } |
| 133 | + return getUsedSizeFromProcMemInfo(); |
| 134 | + } |
| 135 | + |
| 136 | + return -1L; |
| 137 | + } |
| 138 | + |
| 139 | + // Will be removed as part of GR-51479. |
| 140 | + private static long getUsedSizeFromProcMemInfo() { |
| 141 | + try { |
| 142 | + List<String> lines = readAllLines("/proc/meminfo"); |
| 143 | + for (String line : lines) { |
| 144 | + if (line.contains("MemAvailable")) { |
| 145 | + return size().rawValue() - parseFirstNumber(line) * K; |
| 146 | + } |
| 147 | + } |
| 148 | + } catch (Exception e) { |
| 149 | + /* Nothing to do. */ |
| 150 | + } |
| 151 | + return -1L; |
| 152 | + } |
| 153 | + |
| 154 | + private static List<String> readAllLines(String fileName) throws IOException { |
| 155 | + List<String> lines = new ArrayList<>(); |
| 156 | + try (BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName, StandardCharsets.UTF_8))) { |
| 157 | + String line; |
| 158 | + while ((line = bufferedReader.readLine()) != null) { |
| 159 | + lines.add(line); |
| 160 | + } |
| 161 | + } |
| 162 | + return lines; |
| 163 | + } |
| 164 | + |
| 165 | + /** Parses the first number in the String as a long value. */ |
| 166 | + private static long parseFirstNumber(String str) { |
| 167 | + int firstDigit = -1; |
| 168 | + int lastDigit = -1; |
| 169 | + |
| 170 | + for (int i = 0; i < str.length(); i++) { |
| 171 | + if (Character.isDigit(str.charAt(i))) { |
| 172 | + if (firstDigit == -1) { |
| 173 | + firstDigit = i; |
143 | 174 | } |
144 | | - } catch (IOException e) { |
| 175 | + lastDigit = i; |
| 176 | + } else if (firstDigit != -1) { |
| 177 | + break; |
145 | 178 | } |
146 | 179 | } |
| 180 | + |
| 181 | + if (firstDigit >= 0) { |
| 182 | + String number = str.substring(firstDigit, lastDigit + 1); |
| 183 | + return Long.parseLong(number); |
| 184 | + } |
147 | 185 | return -1; |
148 | 186 | } |
149 | 187 |
|
|
0 commit comments