ASA
ASA

Reputation: 1971

get real RAM usage of current JVM with Java

In HTOP you can see the RES value (resident size) which shows how much of your RAM your JVM process is really taking.

Now I want to get that value by only using pure Java. If you tell me it's just not possible, that's fine as well.

Let me explain all the attempts I made with an application that shows a RES value of 887M in htop:

  1. Combining committed HeapMemory and non Heapmemory via MemoryMXBean gives me 726M
  2. Adding up all commited memory of all ManagementFactory.getMemoryPoolMXBeans() gives me 737M
  3. runtime.totalMemory() gives 515M

Any ideas what else I could try?

Upvotes: 5

Views: 3483

Answers (2)

Pwnstar
Pwnstar

Reputation: 2245

I've written:

public class RuntimeUtil {
private static final long MEGABYTE_FACTOR = 1024L * 1024L;
private static final DecimalFormat ROUNDED_DOUBLE_DECIMALFORMAT;
private static final String MIB = "MiB";

static {
    DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(Locale.ENGLISH);
    otherSymbols.setDecimalSeparator('.');
    otherSymbols.setGroupingSeparator(',');
    ROUNDED_DOUBLE_DECIMALFORMAT = new DecimalFormat("####0.00", otherSymbols);
    ROUNDED_DOUBLE_DECIMALFORMAT.setGroupingUsed(false);
}

private RuntimeUtil() {
    //No Init
}

public static long getMaxMemory() {
    return Runtime.getRuntime().maxMemory();
}

public static long getUsedMemory() {
    return getMaxMemory() - getFreeMemory();
}

public static long getTotalMemory() {
    return Runtime.getRuntime().totalMemory();
}

public static long getFreeMemory() {
    return Runtime.getRuntime().freeMemory();
}

public static String getTotalMemoryInMiB() {
    double totalMiB = bytesToMiB(getTotalMemory());
    return String.format("%s %s", ROUNDED_DOUBLE_DECIMALFORMAT.format(totalMiB), MIB);
}

public static String getFreeMemoryInMiB() {
    double freeMiB = bytesToMiB(getFreeMemory());
    return String.format("%s %s", ROUNDED_DOUBLE_DECIMALFORMAT.format(freeMiB), MIB);
}

public static String getUsedMemoryInMiB() {
    double usedMiB = bytesToMiB(getUsedMemory());
    return String.format("%s %s", ROUNDED_DOUBLE_DECIMALFORMAT.format(usedMiB), MIB);
}

public static String getMaxMemoryInMiB() {
    double maxMiB = bytesToMiB(getMaxMemory());
    return String.format("%s %s", ROUNDED_DOUBLE_DECIMALFORMAT.format(maxMiB), MIB);
}

public static double getPercentageUsed() {
    return ((double) getUsedMemory() / getMaxMemory()) * 100;
}

public static String getPercentageUsedFormatted() {
    double usedPercentage = getPercentageUsed();
    return ROUNDED_DOUBLE_DECIMALFORMAT.format(usedPercentage) + "%";
}

private static double bytesToMiB(long bytes) {
    return ((double) bytes / MEGABYTE_FACTOR);
}

public static String getHostAdress() {
    try {
        java.net.InetAddress addr = java.net.InetAddress.getLocalHost();
        return addr.getHostAddress();
    } catch (UnknownHostException e) {
        // looks like a strange machine
        System.out.println(e.getMessage());
    }
    return StringUtil.EMPTY;
}

public static String getHostName() {
    try {
        java.net.InetAddress addr = java.net.InetAddress.getLocalHost();
        return addr.getHostName();
    } catch (UnknownHostException e) {
        // looks like a strange machine
        System.out.println(e.getMessage());
    }
    return StringUtil.EMPTY;
}

public static String getSystemInformation() {
    return String.format("SystemInfo=Current heap:%s; Used:%s; Free:%s; Maximum Heap:%s; Percentage Used:%s",
            getTotalMemoryInMiB(),
            getUsedMemoryInMiB(),
            getFreeMemoryInMiB(),
            getMaxMemoryInMiB(),
            getPercentageUsedFormatted());
}

Upvotes: 3

apangin
apangin

Reputation: 98304

Assuming you are running Linux, just read /proc/self/status file and look for VmRSS: line.

Or parse /proc/self/smaps to get comprehensive memory information for the current process.

Upvotes: 3

Related Questions