This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch CAUSEWAY-3886 in repository https://gitbox.apache.org/repos/asf/causeway.git
commit b794e379042db1ab8aa9f4b65aceabf7e7a05b31 Author: Dan Haywood <[email protected]> AuthorDate: Sun Apr 27 13:26:13 2025 +0100 ESP-3886 : adds utility to measure metaclass memory usage. --- commons/src/main/java/module-info.java | 2 + .../causeway/commons/memory/MemoryUsage.java | 67 ++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/commons/src/main/java/module-info.java b/commons/src/main/java/module-info.java index 4d09aa72aaa..92e4474ad9c 100644 --- a/commons/src/main/java/module-info.java +++ b/commons/src/main/java/module-info.java @@ -79,8 +79,10 @@ requires com.fasterxml.jackson.datatype.jsr310; requires com.fasterxml.jackson.dataformat.yaml; requires com.fasterxml.jackson.datatype.jdk8; + requires java.management; opens org.apache.causeway.commons.internal.resources to java.xml.bind, com.sun.xml.bind; // JUnit test opens org.apache.causeway.commons.io to java.xml.bind, com.sun.xml.bind; + exports org.apache.causeway.commons.memory; } \ No newline at end of file diff --git a/commons/src/main/java/org/apache/causeway/commons/memory/MemoryUsage.java b/commons/src/main/java/org/apache/causeway/commons/memory/MemoryUsage.java new file mode 100644 index 00000000000..005526e6230 --- /dev/null +++ b/commons/src/main/java/org/apache/causeway/commons/memory/MemoryUsage.java @@ -0,0 +1,67 @@ +package org.apache.causeway.commons.memory; + +import lombok.SneakyThrows; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryPoolMXBean; +import java.util.concurrent.Callable; + +public class MemoryUsage { + + private MemoryUsage(java.lang.management.MemoryUsage usage) { + this(usage.getUsed() / 1024); + } + + private MemoryUsage(final long usedInKb) { + this.usedInKb = usedInKb; + } + + final long usedInKb; + + @Override + public String toString() { + return String.format("%,d KB", usedInKb); + } + + public static void measureMetaspace(String desc, final Runnable runnable) { + MemoryUsage before = metaspace(); + try { + runnable.run(); + } finally { + MemoryUsage after = metaspace(); + System.out.printf("%s : %s%n", after.minus(before), desc); + } + } + + static int indent = 0; + + @SneakyThrows + public static <T> T measureMetaspace(final String desc, final Callable<T> runnable) { + MemoryUsage before = metaspace(); + try { + indent++; + return runnable.call(); + } finally { + MemoryUsage after = metaspace(); + System.out.printf("%s%s : %s%n", spaces(indent), after.minus(before), desc); + indent--; + } + } + + private static String spaces(int indent) { + return " ".repeat(indent * 2); + } + + private MemoryUsage minus(MemoryUsage before) { + return new MemoryUsage(this.usedInKb - before.usedInKb); + } + + public static MemoryUsage metaspace() { + for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) { + if (pool.getName().contains("Metaspace")) { + return new MemoryUsage(pool.getUsage()); + } + } + throw new RuntimeException("Metaspace Usage not found"); + } +}
