|
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