IDE: IntelliJ, JDK 16.0.2
Code:
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
System.out.println("Free memory before gc: " + runtime.freeMemory() / (1024 * 1024) + " Mb");
runtime.gc();
System.out.println("Free memory after gc: " + runtime.freeMemory() / (1024 * 1024) + " Mb");
}
Output:
Free memory before gc: 251 Mb
Free memory after gc: 13 Mb
Question: Why calling to Garbage collection "eat" all memory?
Mind the documentation of freeMemory()
:
Returns the amount of free memory in the Java Virtual Machine.
and compare to totalMemory()
:
Returns the total amount of memory in the Java virtual machine. The value returned by this method may vary over time, depending on the host environment.
So, change your program to
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
log("before gc", runtime);
runtime.gc();
log("after gc", runtime);
}
static void log(String point, Runtime runtime) {
System.out.println("Free memory " + point + ": "
+ runtime.freeMemory() / (1024 * 1024) + " MB of "
+ runtime.totalMemory() / (1024 * 1024) + " MB");
}
On my machine, it prints
Free memory before gc: 253 MB of 256 MB
Free memory after gc: 13 MB of 14 MB
indicating that the garbage collection did not only free memory, but gave it back to the operating system.
The default configuration is designed to suite larger applications and performing a (full) garbage collection with such a low memory usage is rather unusual. So it’s not surprising that the heap had a larger initial size and got reduced by this forced garbage collection.
When I run the same program with the -Xms14M
option, I get
Free memory before gc: 12 MB of 14 MB
Free memory after gc: 13 MB of 14 MB