Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to measure memory usage

Short answer

The used heap memory is totalMemory() - freeMemory() of the Runtime object. The numbers depend on the machine and change from run to run:

void main() {
    Runtime rt = Runtime.getRuntime();
    long usedMb = (rt.totalMemory() - rt.freeMemory()) / (1024 * 1024);
    IO.println("Used: " + usedMb + " MB");
}

Output:

Used: 42 MB

All three numbers

maxMemory() is the heap limit, totalMemory() is how much the JVM has already taken from the system, freeMemory() is the free part of it:

void main() {
    Runtime rt = Runtime.getRuntime();
    long mb = 1024 * 1024;
 
    IO.println("Max:   " + rt.maxMemory() / mb + " MB");
    IO.println("Total: " + rt.totalMemory() / mb + " MB");
    IO.println("Free:  " + rt.freeMemory() / mb + " MB");
}

Output:

Max:   4080 MB
Total: 258 MB
Free:  213 MB

Memory taken by an operation

Compare the used memory before and after. Here it is an array of 10 million long values, 8 bytes each:

long usedMb() {
    Runtime rt = Runtime.getRuntime();
    return (rt.totalMemory() - rt.freeMemory()) / (1024 * 1024);
}
 
void main() {
    long before = usedMb();
    long[] numbers = new long[10_000_000];
    long after = usedMb();
 
    IO.println(numbers.length + " numbers");
    IO.println("About " + (after - before) + " MB");
}

Output:

10000000 numbers
About 78 MB

The memory limit

The heap limit is set with -Xmx at startup, for example java -Xmx256m Main.java:

void main() {
    IO.println(Runtime.getRuntime().maxMemory() / (1024 * 1024) + " MB");
}

Output:

256 MB

Common mistake

Treating the result as exact. The garbage collector frees memory when it decides to, so the before/after difference may include objects that are no longer needed or even turn out negative. System.gc() before measuring only asks the JVM to collect garbage. For accurate analysis use tools: VisualVM, JDK Mission Control or jcmd <pid> GC.heap_info.

Functions used in this recipe

  • Runtime.getRuntime() — Returns the Runtime object of the current JVM: memory, processor count, shutdown hooks.
  • System.nanoTime() — Returns a high-resolution timer value in nanoseconds — for measuring durations. See also currentTimeMillis().
  • System.exit() — Terminates the program immediately with the given exit code.

Thanks for reading!

Donate to the site — we work hard for you.