Skip to content

Commit

Permalink
Merge pull request #4946 from MovingBlocks/feat/debugOverlayRSS
Browse files Browse the repository at this point in the history
  • Loading branch information
keturn authored Nov 15, 2021
2 parents f105255 + f414d22 commit ce8d34f
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.terasology.engine.persistence.StorageManager;
import org.terasology.engine.registry.In;
import org.terasology.engine.rendering.nui.CoreScreenLayer;
import org.terasology.engine.utilities.OperatingSystemMemory;
import org.terasology.engine.world.WorldProvider;
import org.terasology.engine.world.chunks.Chunks;
import org.terasology.nui.databinding.ReadOnlyBinding;
Expand All @@ -31,7 +32,7 @@
*/
public class DebugOverlay extends CoreScreenLayer {

public static final double MB_SIZE = 1048576.0;
public static final float MB_SIZE = 1048576.0f;

@In
private Config config;
Expand Down Expand Up @@ -72,13 +73,40 @@ public Boolean get() {
});

UILabel debugLine1 = find("debugLine1", UILabel.class);

// This limit doesn't change after start-up.
final long dataLimit = OperatingSystemMemory.isAvailable()
? OperatingSystemMemory.dataAndStackSizeLimit() : -1;

if (debugLine1 != null) {
debugLine1.bindText(new ReadOnlyBinding<String>() {
debugLine1.bindText(new ReadOnlyBinding<>() {
@Override
public String get() {
double memoryUsage = ((double) Runtime.getRuntime().totalMemory() - (double) Runtime.getRuntime().freeMemory()) / MB_SIZE;
return String.format("FPS: %.2f, Memory Usage: %.2f MB, Total Memory: %.2f MB, Max Memory: %.2f MB",
time.getFps(), memoryUsage, Runtime.getRuntime().totalMemory() / MB_SIZE, Runtime.getRuntime().maxMemory() / MB_SIZE);
Runtime runtime = Runtime.getRuntime();
long totalHeapSize = runtime.totalMemory();
float usedHeapMemory = ((float) totalHeapSize - (float) runtime.freeMemory()) / MB_SIZE;
String s = String.format(
"FPS: %.1f, Heap Usage: %.1f MB, Total Heap: %.1f MB, Max Heap: %.1f MB",
time.getFps(),
usedHeapMemory,
totalHeapSize / MB_SIZE,
runtime.maxMemory() / MB_SIZE
);
if (OperatingSystemMemory.isAvailable()) {
// Check data size, because that's the one comparable to Terasology#setMemoryLimit
long dataSize = OperatingSystemMemory.dataAndStackSize();
// How much bigger is that than the number reported by the Java runtime?
long nonJavaHeapDataSize = dataSize - totalHeapSize;
String limitString = (dataLimit > 0)
? String.format(" / %.1f MB (%02d%%)", dataLimit / MB_SIZE, 100 * dataSize / dataLimit)
: "";
return String.format(
"%s, Data: %.1f MB%s, Extra: %.1f MB",
s, dataSize / MB_SIZE, limitString, nonJavaHeapDataSize / MB_SIZE
);
} else {
return s;
}
}
});
}
Expand Down Expand Up @@ -158,7 +186,7 @@ public String get() {
debugInfo.bindText(new ReadOnlyBinding<String>() {
@Override
public String get() {
return String.format("[H] : Debug Documentation");
return "[H] : Debug Documentation";
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ public MetricsMode(String name) {
*/
public abstract boolean isAvailable();

public abstract boolean isPerformanceManagerMode();
public boolean isPerformanceManagerMode() {
return false;
}

/**
* A (human readable) name for the metrics mode.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,4 @@ public String getMetrics() {
public boolean isAvailable() {
return networkSystem.getMode() != NetworkMode.NONE;
}

@Override
public boolean isPerformanceManagerMode() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,4 @@ public String getMetrics() {
public boolean isAvailable() {
return true;
}

@Override
public boolean isPerformanceManagerMode() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,4 @@ public String getMetrics() {
public boolean isAvailable() {
return true;
}

@Override
public boolean isPerformanceManagerMode() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,4 @@ public String getMetrics() {
public boolean isAvailable() {
return CoreRegistry.get(WorldRenderer.class) != null;
}

@Override
public boolean isPerformanceManagerMode() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0

package org.terasology.engine.utilities;

import com.sun.jna.platform.unix.LibC;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;

/**
* Monitor process memory usage.
* <p>
* This checks process's total memory usage as seen by the operating system.
* This includes memory not managed by the JVM.
*/
public final class OperatingSystemMemory {
public static final int PAGE_SIZE = 1 << 12; // 4 kB on x86 platforms

private static final Path PROC_STATM = Path.of("/proc/self/statm");

private OperatingSystemMemory() { }

public static boolean isAvailable() {
return OS.IS_LINUX;
}

public static long residentSetSize() {
try {
return STATM.RESIDENT.inBytes(Files.readString(PROC_STATM));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

public static long dataAndStackSize() {
try {
return STATM.DATA.inBytes(Files.readString(PROC_STATM));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

public static long dataAndStackSizeLimit() {
final LibC.Rlimit dataLimit = new LibC.Rlimit();
LibC.INSTANCE.getrlimit(LibC.RLIMIT_DATA, dataLimit);
return dataLimit.rlim_cur;
}

/**
* The fields of /proc/[pid]/statm
* <p>
* Note from proc(5):
* <blockquote><p>
* Some of these values are inaccurate because of a kernel-internal scalability optimization.
* If accurate values are required, use /proc/[pid]/smaps or /proc/[pid]/smaps_rollup instead,
* which are much slower but provide accurate, detailed information.
* </p></blockquote>
*/
enum STATM {
/** total program size */
SIZE(0),
/** resident set size */
RESIDENT(1),
/** number of resident shared pages */
SHARED(2),
/** text (code) */
TEXT(3),
/** unused since Linux 2.6 */
LIB(4),
/** data + stack */
DATA(5),
/** unused since Linux 2.6 */
DT(6);

private final short index;

STATM(int i) {
index = (short) i;
}

public long rawValue(String line) {
return Long.parseLong(line.split(" ")[index]);
}

public long inBytes(String line) {
return rawValue(line) * PAGE_SIZE;
}
}
}

0 comments on commit ce8d34f

Please sign in to comment.