Oops – Memory Leaks in Java

Some interesting stuff:
Most people think Java cannot leak memory, but actually that’s not true. Java, unlike languages such as C or Javascript, can have two kinds of memory leaks:

  • True leaks – unreferenced, unrecoverable segments of memory
  • Soft leaks – memory that could be garbage collected, but is “accidentally” referenced

The first kind of memory leak, the true leak, is common to C. It’s trivially easy to write a C program which leaks memory like a sieve by simple putting a call to malloc() inside a tight loop. This creates unbounded amounts of heap memory and eventually runs out of space. Additionally, the memory is lost if you don’t save a pointer to it. However, the same program in Java will not run out of memory.
Unfortunately, though, there is a way to create true memory leaks in java, and that is with a poor implementation of the finalize method,

The finalize method exists on every Object and is called by the garbage collector’s thread before it reclaims that memory. So, the simplest thing we can do to prevent the garbage collector from reclaiming it is to yield execution:

public class finalizer {
protected void finalize() throws Throwable {
while (true) {
Thread.yield();
}
}
public static void main(String[] args) {
while (true) {
for (int i = 0; i < 100000; i++) {
finalizer f = new finalizer();
}
System.out.println("" + Runtime.getRuntime().freeMemory()
+ " bytes free!");
}
}
}


This produces a quick memory leak and Out of Memory Exception:

12591736 bytes free!
8599816 bytes free!
4584576 bytes free!
602496 bytes free!
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space

Throwing any kind of Exception or Error from finalize() also prevents the garbage collector from reclaiming the memory
Source