Skip to content

Commit 1f19cf1

Browse files
Cleanups.
1 parent 06d51ac commit 1f19cf1

File tree

2 files changed

+80
-44
lines changed

2 files changed

+80
-44
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/PhysicalMemory.java

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
*/
2525
package com.oracle.svm.core.heap;
2626

27+
import java.io.BufferedReader;
28+
import java.io.FileReader;
2729
import java.io.IOException;
2830
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;
3133
import java.util.List;
3234
import java.util.concurrent.locks.ReentrantLock;
3335

@@ -44,7 +46,6 @@
4446
import com.oracle.svm.core.thread.VMOperation;
4547
import com.oracle.svm.core.util.UnsignedUtils;
4648
import com.oracle.svm.core.util.VMError;
47-
4849
import com.sun.management.OperatingSystemMXBean;
4950

5051
/**
@@ -117,33 +118,70 @@ public static UnsignedWord size() {
117118
return cachedSize;
118119
}
119120

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. */
123122
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)) {
128127
OperatingSystemMXBean osBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
129128
return osBean.getTotalMemorySize() - osBean.getFreeMemorySize();
130129
}
131-
// Non-containerized Linux uses MemAvailable from /proc/meminfo
130+
131+
// Non-containerized Linux uses /proc/meminfo.
132132
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;
143174
}
144-
} catch (IOException e) {
175+
lastDigit = i;
176+
} else if (firstDigit != -1) {
177+
break;
145178
}
146179
}
180+
181+
if (firstDigit >= 0) {
182+
String number = str.substring(firstDigit, lastDigit + 1);
183+
return Long.parseLong(number);
184+
}
147185
return -1;
148186
}
149187

substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestEveryChunkNativePeriodicEvents.java

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,55 +28,53 @@
2828

2929
import static org.junit.Assert.assertTrue;
3030

31-
import com.oracle.svm.core.jfr.JfrEvent;
32-
3331
import java.util.List;
3432

33+
import org.junit.Test;
34+
35+
import com.oracle.svm.core.jfr.JfrEvent;
36+
3537
import jdk.jfr.Recording;
3638
import jdk.jfr.consumer.RecordedEvent;
37-
import org.junit.Test;
3839

3940
/**
40-
* This tests built in native JFR events that are sent periodically upon every chunk. The events
41-
* ThreadCPULoad and ThreadAllocationStatistics are not tested here since they already have their
42-
* own individual tests.
41+
* Tests the VM-level JFR events that are created periodically upon every chunk. Note that the
42+
* events ThreadCPULoad and ThreadAllocationStatistics are not tested here since they already have
43+
* their own individual tests.
4344
*/
4445
public class TestEveryChunkNativePeriodicEvents extends JfrRecordingTest {
45-
4646
@Test
4747
public void test() throws Throwable {
48-
String[] events = new String[]{
49-
JfrEvent.JavaThreadStatistics.getName(),
50-
JfrEvent.PhysicalMemory.getName(),
51-
JfrEvent.ClassLoadingStatistics.getName(),
52-
};
48+
String[] events = new String[]{JfrEvent.JavaThreadStatistics.getName(), JfrEvent.PhysicalMemory.getName(), JfrEvent.ClassLoadingStatistics.getName()};
5349
Recording recording = startRecording(events);
54-
55-
stopRecording(recording, this::validateEvents);
50+
stopRecording(recording, TestEveryChunkNativePeriodicEvents::validateEvents);
5651
}
5752

58-
private void validateEvents(List<RecordedEvent> events) {
53+
private static void validateEvents(List<RecordedEvent> events) {
5954
boolean foundJavaThreadStatistics = false;
6055
boolean foundPhysicalMemory = false;
6156
boolean foundClassLoadingStatistics = false;
57+
6258
for (RecordedEvent e : events) {
63-
if (e.getEventType().getName().equals(JfrEvent.JavaThreadStatistics.getName())) {
59+
String eventName = e.getEventType().getName();
60+
if (eventName.equals(JfrEvent.JavaThreadStatistics.getName())) {
6461
foundJavaThreadStatistics = true;
6562
assertTrue(e.getLong("activeCount") > 1);
6663
assertTrue(e.getLong("daemonCount") > 0);
6764
assertTrue(e.getLong("accumulatedCount") > 1);
6865
assertTrue(e.getLong("peakCount") > 1);
69-
} else if (e.getEventType().getName().equals(JfrEvent.PhysicalMemory.getName())) {
66+
} else if (eventName.equals(JfrEvent.PhysicalMemory.getName())) {
7067
foundPhysicalMemory = true;
7168
assertTrue(e.getLong("totalSize") > 0);
72-
assertTrue(e.getLong("usedSize") > 0 || e.getLong("usedSize") == -1);
73-
74-
} else if (e.getEventType().getName().equals(JfrEvent.ClassLoadingStatistics.getName())) {
69+
assertTrue(e.getLong("usedSize") > 0);
70+
} else if (eventName.equals(JfrEvent.ClassLoadingStatistics.getName())) {
7571
foundClassLoadingStatistics = true;
7672
assertTrue(e.getLong("loadedClassCount") > 0);
7773
}
7874
}
79-
assertTrue(foundJavaThreadStatistics && foundPhysicalMemory && foundClassLoadingStatistics);
80-
}
8175

76+
assertTrue(foundJavaThreadStatistics);
77+
assertTrue(foundPhysicalMemory);
78+
assertTrue(foundClassLoadingStatistics);
79+
}
8280
}

0 commit comments

Comments
 (0)