Skip to content

Commit

Permalink
Cleanups.
Browse files Browse the repository at this point in the history
  • Loading branch information
christianhaeubl committed Mar 28, 2024
1 parent 06d51ac commit 1f19cf1
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 44 deletions.
Expand Up @@ -24,10 +24,12 @@
*/
package com.oracle.svm.core.heap;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

Expand All @@ -44,7 +46,6 @@
import com.oracle.svm.core.thread.VMOperation;
import com.oracle.svm.core.util.UnsignedUtils;
import com.oracle.svm.core.util.VMError;

import com.sun.management.OperatingSystemMXBean;

/**
Expand Down Expand Up @@ -117,33 +118,70 @@ public static UnsignedWord size() {
return cachedSize;
}

/**
* Returns the amount of used physical memory in bytes, or -1 if not supported yet.
*/
/** Returns the amount of used physical memory in bytes, or -1 if not supported. */
public static long usedSize() {
// Containerized Linux, Windows and Mac OS X use the OS bean
if ((Containers.isContainerized() && Containers.memoryLimitInBytes() > 0) ||
Platform.includedIn(Platform.WINDOWS.class) ||
Platform.includedIn(Platform.MACOS.class)) {
// Windows, macOS, and containerized Linux use the OS bean.
if (Platform.includedIn(Platform.WINDOWS.class) ||
Platform.includedIn(Platform.MACOS.class) ||
(Containers.isContainerized() && Containers.memoryLimitInBytes() > 0)) {
OperatingSystemMXBean osBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
return osBean.getTotalMemorySize() - osBean.getFreeMemorySize();
}
// Non-containerized Linux uses MemAvailable from /proc/meminfo

// Non-containerized Linux uses /proc/meminfo.
if (Platform.includedIn(Platform.LINUX.class)) {
try {
List<String> lines = Files.readAllLines(Paths.get("/proc/meminfo"));
for (String line : lines) {
if (!line.contains("MemAvailable")) {
continue;
}
String memAvailable = line.replaceAll("\\D", "");
if (!memAvailable.isEmpty()) {
return size().rawValue() - Long.parseLong(memAvailable) * K;
}
return getUsedSizeFromProcMemInfo();
}

return -1L;
}

// Will be removed as part of GR-51479.
private static long getUsedSizeFromProcMemInfo() {
try {
List<String> lines = readAllLines("/proc/meminfo");
for (String line : lines) {
if (line.contains("MemAvailable")) {
return size().rawValue() - parseFirstNumber(line) * K;
}
}
} catch (Exception e) {
/* Nothing to do. */
}
return -1L;
}

private static List<String> readAllLines(String fileName) throws IOException {
List<String> lines = new ArrayList<>();
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName, StandardCharsets.UTF_8))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
}
}
return lines;
}

/** Parses the first number in the String as a long value. */
private static long parseFirstNumber(String str) {
int firstDigit = -1;
int lastDigit = -1;

for (int i = 0; i < str.length(); i++) {
if (Character.isDigit(str.charAt(i))) {
if (firstDigit == -1) {
firstDigit = i;
}
} catch (IOException e) {
lastDigit = i;
} else if (firstDigit != -1) {
break;
}
}

if (firstDigit >= 0) {
String number = str.substring(firstDigit, lastDigit + 1);
return Long.parseLong(number);
}
return -1;
}

Expand Down
Expand Up @@ -28,55 +28,53 @@

import static org.junit.Assert.assertTrue;

import com.oracle.svm.core.jfr.JfrEvent;

import java.util.List;

import org.junit.Test;

import com.oracle.svm.core.jfr.JfrEvent;

import jdk.jfr.Recording;
import jdk.jfr.consumer.RecordedEvent;
import org.junit.Test;

/**
* This tests built in native JFR events that are sent periodically upon every chunk. The events
* ThreadCPULoad and ThreadAllocationStatistics are not tested here since they already have their
* own individual tests.
* Tests the VM-level JFR events that are created periodically upon every chunk. Note that the
* events ThreadCPULoad and ThreadAllocationStatistics are not tested here since they already have
* their own individual tests.
*/
public class TestEveryChunkNativePeriodicEvents extends JfrRecordingTest {

@Test
public void test() throws Throwable {
String[] events = new String[]{
JfrEvent.JavaThreadStatistics.getName(),
JfrEvent.PhysicalMemory.getName(),
JfrEvent.ClassLoadingStatistics.getName(),
};
String[] events = new String[]{JfrEvent.JavaThreadStatistics.getName(), JfrEvent.PhysicalMemory.getName(), JfrEvent.ClassLoadingStatistics.getName()};
Recording recording = startRecording(events);

stopRecording(recording, this::validateEvents);
stopRecording(recording, TestEveryChunkNativePeriodicEvents::validateEvents);
}

private void validateEvents(List<RecordedEvent> events) {
private static void validateEvents(List<RecordedEvent> events) {
boolean foundJavaThreadStatistics = false;
boolean foundPhysicalMemory = false;
boolean foundClassLoadingStatistics = false;

for (RecordedEvent e : events) {
if (e.getEventType().getName().equals(JfrEvent.JavaThreadStatistics.getName())) {
String eventName = e.getEventType().getName();
if (eventName.equals(JfrEvent.JavaThreadStatistics.getName())) {
foundJavaThreadStatistics = true;
assertTrue(e.getLong("activeCount") > 1);
assertTrue(e.getLong("daemonCount") > 0);
assertTrue(e.getLong("accumulatedCount") > 1);
assertTrue(e.getLong("peakCount") > 1);
} else if (e.getEventType().getName().equals(JfrEvent.PhysicalMemory.getName())) {
} else if (eventName.equals(JfrEvent.PhysicalMemory.getName())) {
foundPhysicalMemory = true;
assertTrue(e.getLong("totalSize") > 0);
assertTrue(e.getLong("usedSize") > 0 || e.getLong("usedSize") == -1);

} else if (e.getEventType().getName().equals(JfrEvent.ClassLoadingStatistics.getName())) {
assertTrue(e.getLong("usedSize") > 0);
} else if (eventName.equals(JfrEvent.ClassLoadingStatistics.getName())) {
foundClassLoadingStatistics = true;
assertTrue(e.getLong("loadedClassCount") > 0);
}
}
assertTrue(foundJavaThreadStatistics && foundPhysicalMemory && foundClassLoadingStatistics);
}

assertTrue(foundJavaThreadStatistics);
assertTrue(foundPhysicalMemory);
assertTrue(foundClassLoadingStatistics);
}
}

0 comments on commit 1f19cf1

Please sign in to comment.